1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 package org.apache.hadoop.hdfs.server.datanode.fsdataset.impl; 19 20 import java.io.File; 21 import java.io.IOException; 22 import java.io.RandomAccessFile; 23 import java.nio.channels.FileChannel; 24 import java.nio.channels.FileLock; 25 import java.nio.channels.OverlappingFileLockException; 26 import java.util.Collection; 27 import java.util.Random; 28 29 import org.apache.hadoop.hdfs.protocol.Block; 30 import org.apache.hadoop.hdfs.protocol.ExtendedBlock; 31 import org.apache.hadoop.hdfs.server.common.Storage; 32 import org.apache.hadoop.hdfs.server.datanode.DataNode; 33 import org.apache.hadoop.hdfs.server.datanode.ReplicaInfo; 34 import org.apache.hadoop.hdfs.server.datanode.StorageLocation; 35 import org.apache.hadoop.hdfs.server.datanode.fsdataset.FsDatasetSpi; 36 import org.apache.hadoop.io.IOUtils; 37 38 import static org.junit.Assert.assertNotNull; 39 import static org.junit.Assert.fail; 40 41 public class FsDatasetTestUtil { 42 getFile(FsDatasetSpi<?> fsd, String bpid, long bid)43 public static File getFile(FsDatasetSpi<?> fsd, String bpid, long bid) { 44 return ((FsDatasetImpl)fsd).getFile(bpid, bid, false); 45 } 46 getBlockFile(FsDatasetSpi<?> fsd, String bpid, Block b )47 public static File getBlockFile(FsDatasetSpi<?> fsd, String bpid, Block b 48 ) throws IOException { 49 return ((FsDatasetImpl)fsd).getBlockFile(bpid, b.getBlockId()); 50 } 51 getMetaFile(FsDatasetSpi<?> fsd, String bpid, Block b)52 public static File getMetaFile(FsDatasetSpi<?> fsd, String bpid, Block b) 53 throws IOException { 54 return FsDatasetUtil.getMetaFile(getBlockFile(fsd, bpid, b), b 55 .getGenerationStamp()); 56 } 57 unlinkBlock(FsDatasetSpi<?> fsd, ExtendedBlock block, int numLinks)58 public static boolean unlinkBlock(FsDatasetSpi<?> fsd, 59 ExtendedBlock block, int numLinks) throws IOException { 60 final ReplicaInfo info = ((FsDatasetImpl)fsd).getReplicaInfo(block); 61 return info.unlinkBlock(numLinks); 62 } 63 fetchReplicaInfo(final FsDatasetSpi<?> fsd, final String bpid, final long blockId)64 public static ReplicaInfo fetchReplicaInfo (final FsDatasetSpi<?> fsd, 65 final String bpid, final long blockId) { 66 return ((FsDatasetImpl)fsd).fetchReplicaInfo(bpid, blockId); 67 } 68 getPendingAsyncDeletions(FsDatasetSpi<?> fsd)69 public static long getPendingAsyncDeletions(FsDatasetSpi<?> fsd) { 70 return ((FsDatasetImpl)fsd).asyncDiskService.countPendingDeletions(); 71 } 72 getReplicas(FsDatasetSpi<?> fsd, String bpid)73 public static Collection<ReplicaInfo> getReplicas(FsDatasetSpi<?> fsd, 74 String bpid) { 75 return ((FsDatasetImpl)fsd).volumeMap.replicas(bpid); 76 } 77 78 /** 79 * Stop the lazy writer daemon that saves RAM disk files to persistent storage. 80 * @param dn 81 */ stopLazyWriter(DataNode dn)82 public static void stopLazyWriter(DataNode dn) { 83 FsDatasetImpl fsDataset = ((FsDatasetImpl) dn.getFSDataset()); 84 ((FsDatasetImpl.LazyWriter) fsDataset.lazyWriter.getRunnable()).stop(); 85 } 86 87 /** 88 * Asserts that the storage lock file in the given directory has been 89 * released. This method works by trying to acquire the lock file itself. If 90 * locking fails here, then the main code must have failed to release it. 91 * 92 * @param dir the storage directory to check 93 * @throws IOException if there is an unexpected I/O error 94 */ assertFileLockReleased(String dir)95 public static void assertFileLockReleased(String dir) throws IOException { 96 StorageLocation sl = StorageLocation.parse(dir); 97 File lockFile = new File(sl.getFile(), Storage.STORAGE_FILE_LOCK); 98 try (RandomAccessFile raf = new RandomAccessFile(lockFile, "rws"); 99 FileChannel channel = raf.getChannel()) { 100 FileLock lock = channel.tryLock(); 101 assertNotNull(String.format( 102 "Lock file at %s appears to be held by a different process.", 103 lockFile.getAbsolutePath()), lock); 104 if (lock != null) { 105 try { 106 lock.release(); 107 } catch (IOException e) { 108 FsDatasetImpl.LOG.warn(String.format("I/O error releasing file lock %s.", 109 lockFile.getAbsolutePath()), e); 110 throw e; 111 } 112 } 113 } catch (OverlappingFileLockException e) { 114 fail(String.format("Must release lock file at %s.", 115 lockFile.getAbsolutePath())); 116 } 117 } 118 } 119