/** Convert an ExtendedBlock to a Json map. */ private static Map<String, Object> toJsonMap(final ExtendedBlock extendedblock) { if (extendedblock == null) { return null; } final Map<String, Object> m = new TreeMap<String, Object>(); m.put("blockPoolId", extendedblock.getBlockPoolId()); m.put("blockId", extendedblock.getBlockId()); m.put("numBytes", extendedblock.getNumBytes()); m.put("generationStamp", extendedblock.getGenerationStamp()); return m; }
private File getBlockFile(String bpid, ExtendedBlock blk) throws IOException { return new File(DatanodeUtil.idToBlockDir(getFinalizedDir(bpid), blk.getBlockId()).toString() + "/" + blk.getBlockName()); }
private synchronized void updateDeletedBlockId(ExtendedBlock block) { Set<Long> blockIds = deletedBlockIds.get(block.getBlockPoolId()); if (blockIds == null) { blockIds = new HashSet<Long>(); deletedBlockIds.put(block.getBlockPoolId(), blockIds); } blockIds.add(block.getBlockId()); numDeletedBlocks++; if (numDeletedBlocks == MAX_DELETED_BLOCKS) { for (Entry<String, Set<Long>> e : deletedBlockIds.entrySet()) { String bpid = e.getKey(); Set<Long> bs = e.getValue(); fsdatasetImpl.removeDeletedBlocks(bpid, bs); bs.clear(); } numDeletedBlocks = 0; } } }
/** * Get File name for a given block. */ private ReplicaInfo getBlockReplica(ExtendedBlock b) throws IOException { return getBlockReplica(b.getBlockPoolId(), b.getBlockId()); }
/** Generate a block token for a specified user */ public Token<BlockTokenIdentifier> generateToken(String userId, ExtendedBlock block, EnumSet<BlockTokenIdentifier.AccessMode> modes, StorageType[] storageTypes, String[] storageIds) throws IOException { BlockTokenIdentifier id = new BlockTokenIdentifier(userId, block .getBlockPoolId(), block.getBlockId(), modes, storageTypes, storageIds, useProto); return new Token<BlockTokenIdentifier>(id, this); }
private static Replica getReplica(ExtendedBlock block, DataNode datanode) throws ReplicaNotFoundException { Replica replica = datanode.data.getReplica(block.getBlockPoolId(), block.getBlockId()); if (replica == null) { throw new ReplicaNotFoundException(block); } return replica; }
private void initReaders() throws IOException { // Store the array indices of source DNs we have read successfully. // In each iteration of read, the successList list may be updated if // some source DN is corrupted or slow. And use the updated successList // list of DNs for next iteration read. successList = new int[minRequiredSources]; StripedBlockReader reader; int nSuccess = 0; for (int i = 0; i < sources.length && nSuccess < minRequiredSources; i++) { reader = createReader(i, 0); readers.add(reader); if (reader.getBlockReader() != null) { initOrVerifyChecksum(reader); successList[nSuccess++] = i; } } if (nSuccess < minRequiredSources) { String error = "Can't find minimum sources required by " + "reconstruction, block id: " + reconstructor.getBlockGroup().getBlockId(); throw new IOException(error); } }
@Override // FsDatasetSpi public long getReplicaVisibleLength(final ExtendedBlock block) throws IOException { try (AutoCloseableLock lock = datasetLock.acquire()) { final Replica replica = getReplicaInfo(block.getBlockPoolId(), block.getBlockId()); if (replica.getGenerationStamp() < block.getGenerationStamp()) { throw new IOException( "replica.getGenerationStamp() < block.getGenerationStamp(), block=" + block + ", replica=" + replica); } return replica.getVisibleLength(); } }
/** * sendBlock() is used to read block and its metadata and stream the data to * either a client or to another datanode. * * @param out stream to which the block is written to * @param baseStream optional. if non-null, <code>out</code> is assumed to * be a wrapper over this stream. This enables optimizations for * sending the data, e.g. * {@link SocketOutputStream#transferToFully(FileChannel, * long, int)}. * @param throttler for sending data. * @return total bytes read, including checksum data. */ long sendBlock(DataOutputStream out, OutputStream baseStream, DataTransferThrottler throttler) throws IOException { final TraceScope scope = datanode.getTracer(). newScope("sendBlock_" + block.getBlockId()); try { return doSendBlock(out, baseStream, throttler); } finally { scope.close(); } }
public void checkAccess(BlockTokenIdentifier id, String userId, ExtendedBlock block, BlockTokenIdentifier.AccessMode mode) throws InvalidToken { if (LOG.isDebugEnabled()) { LOG.debug("Checking access for user=" + userId + ", block=" + block + ", access mode=" + mode + " using " + id); } if (userId != null && !userId.equals(id.getUserId())) { throw new InvalidToken("Block token with " + id + " doesn't belong to user " + userId); } if (!id.getBlockPoolId().equals(block.getBlockPoolId())) { throw new InvalidToken("Block token with " + id + " doesn't apply to block " + block); } if (id.getBlockId() != block.getBlockId()) { throw new InvalidToken("Block token with " + id + " doesn't apply to block " + block); } if (isExpired(id.getExpiryDate())) { throw new InvalidToken("Block token with " + id + " is expired."); } if (!id.getAccessModes().contains(mode)) { throw new InvalidToken("Block token with " + id + " doesn't have " + mode + " permission"); } }
@Override // FsDatasetSpi public BlockLocalPathInfo getBlockLocalPathInfo(ExtendedBlock block) throws IOException { try (AutoCloseableLock lock = datasetLock.acquire()) { final Replica replica = volumeMap.get(block.getBlockPoolId(), block.getBlockId()); if (replica == null) { throw new ReplicaNotFoundException(block); } if (replica.getGenerationStamp() < block.getGenerationStamp()) { throw new IOException( "Replica generation stamp < block generation stamp, block=" + block + ", replica=" + replica); } else if (replica.getGenerationStamp() > block.getGenerationStamp()) { block.setGenerationStamp(replica.getGenerationStamp()); } } ReplicaInfo r = getBlockReplica(block); File blockFile = new File(r.getBlockURI()); File metaFile = new File(r.getMetadataURI()); BlockLocalPathInfo info = new BlockLocalPathInfo(block, blockFile.getAbsolutePath(), metaFile.toString()); return info; }
public ReplicaInPipeline createRbw(ExtendedBlock b) throws IOException { File f = createRbwFile(b.getBlockPoolId(), b.getLocalBlock()); LocalReplicaInPipeline newReplicaInfo = new ReplicaBuilder(ReplicaState.RBW) .setBlockId(b.getBlockId()) .setGenerationStamp(b.getGenerationStamp()) .setFsVolume(this) .setDirectoryToUse(f.getParentFile()) .setBytesToReserve(b.getNumBytes()) .buildLocalReplicaInPipeline(); return newReplicaInfo; }
/** Generate a block token for the located block. */ public void setBlockToken(final LocatedBlock b, final AccessMode mode) throws IOException { if (isBlockTokenEnabled()) { // Use cached UGI if serving RPC calls. if (b.isStriped()) { Preconditions.checkState(b instanceof LocatedStripedBlock); LocatedStripedBlock sb = (LocatedStripedBlock) b; byte[] indices = sb.getBlockIndices(); Token<BlockTokenIdentifier>[] blockTokens = new Token[indices.length]; ExtendedBlock internalBlock = new ExtendedBlock(b.getBlock()); for (int i = 0; i < indices.length; i++) { internalBlock.setBlockId(b.getBlock().getBlockId() + indices[i]); blockTokens[i] = blockTokenSecretManager.generateToken( NameNode.getRemoteUser().getShortUserName(), internalBlock, EnumSet.of(mode), b.getStorageTypes(), b.getStorageIDs()); } sb.setBlockTokens(blockTokens); } b.setBlockToken(blockTokenSecretManager.generateToken( NameNode.getRemoteUser().getShortUserName(), b.getBlock(), EnumSet.of(mode), b.getStorageTypes(), b.getStorageIDs())); } }
@Override // FsDatasetSpi public ReplicaHandler recoverRbw( ExtendedBlock b, long newGS, long minBytesRcvd, long maxBytesRcvd) throws IOException { LOG.info("Recover RBW replica " + b); while (true) { try { try (AutoCloseableLock lock = datasetLock.acquire()) { ReplicaInfo replicaInfo = getReplicaInfo(b.getBlockPoolId(), b.getBlockId()); // check the replica's state if (replicaInfo.getState() != ReplicaState.RBW) { throw new ReplicaNotFoundException( ReplicaNotFoundException.NON_RBW_REPLICA + replicaInfo); } ReplicaInPipeline rbw = (ReplicaInPipeline)replicaInfo; if (!rbw.attemptToSetWriter(null, Thread.currentThread())) { throw new MustStopExistingWriter(rbw); } LOG.info("At " + datanode.getDisplayName() + ", Recovering " + rbw); return recoverRbwImpl(rbw, b, newGS, minBytesRcvd, maxBytesRcvd); } } catch (MustStopExistingWriter e) { e.getReplicaInPipeline().stopWriter( datanode.getDnConf().getXceiverStopTimeout()); } } }
@Override // FsDatasetSpi public InputStream getBlockInputStream(ExtendedBlock b, long seekOffset) throws IOException { ReplicaInfo info; synchronized(this) { info = volumeMap.get(b.getBlockPoolId(), b.getLocalBlock()); } if (info != null && info.getVolume().isTransientStorage()) { ramDiskReplicaTracker.touch(b.getBlockPoolId(), b.getBlockId()); datanode.getMetrics().incrRamDiskBlocksReadHits(); } if(info != null && info.blockDataExists()) { return info.getDataInputStream(seekOffset); } else { throw new IOException("No data exists for block " + b); } }
public ReplicaInPipeline createTemporary(ExtendedBlock b) throws IOException { // create a temporary file to hold block in the designated volume File f = createTmpFile(b.getBlockPoolId(), b.getLocalBlock()); LocalReplicaInPipeline newReplicaInfo = new ReplicaBuilder(ReplicaState.TEMPORARY) .setBlockId(b.getBlockId()) .setGenerationStamp(b.getGenerationStamp()) .setDirectoryToUse(f.getParentFile()) .setBytesToReserve(b.getLocalBlock().getNumBytes()) .setFsVolume(this) .buildLocalReplicaInPipeline(); return newReplicaInfo; }
private void setCachedLocations(LocatedBlock block) { CachedBlock cachedBlock = new CachedBlock(block.getBlock().getBlockId(), (short)0, false); cachedBlock = cachedBlocks.get(cachedBlock); if (cachedBlock == null) { return; } List<DatanodeDescriptor> cachedDNs = cachedBlock.getDatanodes(Type.CACHED); for (DatanodeDescriptor datanode : cachedDNs) { // Filter out cached blocks that do not have a backing replica. // // This should not happen since it means the CacheManager thinks // something is cached that does not exist, but it's a safety // measure. boolean found = false; for (DatanodeInfo loc : block.getLocations()) { if (loc.equals(datanode)) { block.addCachedLoc(loc); found = true; break; } } if (!found) { LOG.warn("Datanode {} is not a valid cache location for block {} " + "because that node does not have a backing replica!", datanode, block.getBlock().getBlockName()); } } }
public ReplicaInfo moveBlockToTmpLocation(ExtendedBlock block, ReplicaInfo replicaInfo, int smallBufferSize, Configuration conf) throws IOException { File[] blockFiles = FsDatasetImpl.copyBlockFiles(block.getBlockId(), block.getGenerationStamp(), replicaInfo, getTmpDir(block.getBlockPoolId()), replicaInfo.isOnTransientStorage(), smallBufferSize, conf); ReplicaInfo newReplicaInfo = new ReplicaBuilder(ReplicaState.TEMPORARY) .setBlockId(replicaInfo.getBlockId()) .setGenerationStamp(replicaInfo.getGenerationStamp()) .setFsVolume(this) .setDirectoryToUse(blockFiles[0].getParentFile()) .setBytesToReserve(0) .build(); newReplicaInfo.setNumBytes(blockFiles[1].length()); return newReplicaInfo; }
/** * Remove the temporary block file (if any) */ @Override // FsDatasetSpi public void unfinalizeBlock(ExtendedBlock b) throws IOException { try (AutoCloseableLock lock = datasetLock.acquire()) { ReplicaInfo replicaInfo = volumeMap.get(b.getBlockPoolId(), b.getLocalBlock()); if (replicaInfo != null && replicaInfo.getState() == ReplicaState.TEMPORARY) { // remove from volumeMap volumeMap.remove(b.getBlockPoolId(), b.getLocalBlock()); // delete the on-disk temp file if (delBlockFromDisk(replicaInfo)) { LOG.warn("Block " + b + " unfinalized and removed. "); } if (replicaInfo.getVolume().isTransientStorage()) { ramDiskReplicaTracker.discardReplica(b.getBlockPoolId(), b.getBlockId(), true); } } } }
public ReplicaInPipeline convertTemporaryToRbw(ExtendedBlock b, ReplicaInfo temp) throws IOException { final long blockId = b.getBlockId(); final long expectedGs = b.getGenerationStamp(); final long visible = b.getNumBytes(); final long numBytes = temp.getNumBytes(); // move block files to the rbw directory BlockPoolSlice bpslice = getBlockPoolSlice(b.getBlockPoolId()); final File dest = FsDatasetImpl.moveBlockFiles(b.getLocalBlock(), temp, bpslice.getRbwDir()); // create RBW final LocalReplicaInPipeline rbw = new ReplicaBuilder(ReplicaState.RBW) .setBlockId(blockId) .setLength(numBytes) .setGenerationStamp(expectedGs) .setFsVolume(this) .setDirectoryToUse(dest.getParentFile()) .setWriterThread(Thread.currentThread()) .setBytesToReserve(0) .buildLocalReplicaInPipeline(); rbw.setBytesAcked(visible); // load last checksum and datalen final File destMeta = FsDatasetUtil.getMetaFile(dest, b.getGenerationStamp()); byte[] lastChunkChecksum = loadLastPartialChunkChecksum(dest, destMeta); rbw.setLastChecksumAndDataLen(numBytes, lastChunkChecksum); return rbw; }