001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hdfs.server.datanode.fsdataset;
019
020
021import java.io.File;
022import java.io.IOException;
023import java.io.InputStream;
024import java.util.List;
025import java.util.Map;
026
027import org.apache.hadoop.classification.InterfaceAudience;
028import org.apache.hadoop.conf.Configuration;
029import org.apache.hadoop.hdfs.DFSConfigKeys;
030import org.apache.hadoop.hdfs.protocol.Block;
031import org.apache.hadoop.hdfs.protocol.BlockListAsLongs;
032import org.apache.hadoop.hdfs.protocol.BlockLocalPathInfo;
033import org.apache.hadoop.hdfs.protocol.ExtendedBlock;
034import org.apache.hadoop.hdfs.protocol.HdfsBlocksMetadata;
035import org.apache.hadoop.hdfs.server.datanode.DataNode;
036import org.apache.hadoop.hdfs.server.datanode.DataStorage;
037import org.apache.hadoop.hdfs.server.datanode.FinalizedReplica;
038import org.apache.hadoop.hdfs.server.datanode.Replica;
039import org.apache.hadoop.hdfs.server.datanode.ReplicaInPipelineInterface;
040import org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetFactory;
041import org.apache.hadoop.hdfs.server.datanode.metrics.FSDatasetMBean;
042import org.apache.hadoop.hdfs.server.protocol.BlockRecoveryCommand.RecoveringBlock;
043import org.apache.hadoop.hdfs.server.protocol.DatanodeStorage;
044import org.apache.hadoop.hdfs.server.protocol.ReplicaRecoveryInfo;
045import org.apache.hadoop.hdfs.server.protocol.StorageReport;
046import org.apache.hadoop.util.DiskChecker.DiskErrorException;
047import org.apache.hadoop.util.ReflectionUtils;
048
049/**
050 * This is a service provider interface for the underlying storage that
051 * stores replicas for a data node.
052 * The default implementation stores replicas on local drives. 
053 */
054@InterfaceAudience.Private
055public interface FsDatasetSpi<V extends FsVolumeSpi> extends FSDatasetMBean {
056  /**
057   * A factory for creating {@link FsDatasetSpi} objects.
058   */
059  public static abstract class Factory<D extends FsDatasetSpi<?>> {
060    /** @return the configured factory. */
061    public static Factory<?> getFactory(Configuration conf) {
062      @SuppressWarnings("rawtypes")
063      final Class<? extends Factory> clazz = conf.getClass(
064          DFSConfigKeys.DFS_DATANODE_FSDATASET_FACTORY_KEY,
065          FsDatasetFactory.class,
066          Factory.class);
067      return ReflectionUtils.newInstance(clazz, conf);
068    }
069
070    /** Create a new object. */
071    public abstract D newInstance(DataNode datanode, DataStorage storage,
072        Configuration conf) throws IOException;
073
074    /** Does the factory create simulated objects? */
075    public boolean isSimulated() {
076      return false;
077    }
078  }
079
080  /**
081   * Create rolling logs.
082   *
083   * @param prefix the prefix of the log names.
084   * @return rolling logs
085   */
086  public RollingLogs createRollingLogs(String bpid, String prefix
087      ) throws IOException;
088
089  /** @return a list of volumes. */
090  public List<V> getVolumes();
091
092  /** @return a storage with the given storage ID */
093  public DatanodeStorage getStorage(final String storageUuid);
094
095  /** @return one or more storage reports for attached volumes. */
096  public StorageReport[] getStorageReports(String bpid)
097      throws IOException;
098
099  /** @return the volume that contains a replica of the block. */
100  public V getVolume(ExtendedBlock b);
101
102  /** @return a volume information map (name => info). */
103  public Map<String, Object> getVolumeInfoMap();
104
105  /** @return a list of finalized blocks for the given block pool. */
106  public List<FinalizedReplica> getFinalizedBlocks(String bpid);
107
108  /**
109   * Check whether the in-memory block record matches the block on the disk,
110   * and, in case that they are not matched, update the record or mark it
111   * as corrupted.
112   */
113  public void checkAndUpdate(String bpid, long blockId, File diskFile,
114      File diskMetaFile, FsVolumeSpi vol);
115
116  /**
117   * @param b - the block
118   * @return a stream if the meta-data of the block exists;
119   *         otherwise, return null.
120   * @throws IOException
121   */
122  public LengthInputStream getMetaDataInputStream(ExtendedBlock b
123      ) throws IOException;
124
125  /**
126   * Returns the specified block's on-disk length (excluding metadata)
127   * @param b
128   * @return   the specified block's on-disk length (excluding metadta)
129   * @throws IOException
130   */
131  public long getLength(ExtendedBlock b) throws IOException;
132
133  /**
134   * Get reference to the replica meta info in the replicasMap. 
135   * To be called from methods that are synchronized on {@link FSDataset}
136   * @param blockId
137   * @return replica from the replicas map
138   */
139  @Deprecated
140  public Replica getReplica(String bpid, long blockId);
141
142  /**
143   * @return replica meta information
144   */
145  public String getReplicaString(String bpid, long blockId);
146
147  /**
148   * @return the generation stamp stored with the block.
149   */
150  public Block getStoredBlock(String bpid, long blkid) throws IOException;
151  
152  /**
153   * Returns an input stream at specified offset of the specified block
154   * @param b
155   * @param seekOffset
156   * @return an input stream to read the contents of the specified block,
157   *  starting at the offset
158   * @throws IOException
159   */
160  public InputStream getBlockInputStream(ExtendedBlock b, long seekOffset)
161            throws IOException;
162
163  /**
164   * Returns an input stream at specified offset of the specified block
165   * The block is still in the tmp directory and is not finalized
166   * @param b
167   * @param blkoff
168   * @param ckoff
169   * @return an input stream to read the contents of the specified block,
170   *  starting at the offset
171   * @throws IOException
172   */
173  public ReplicaInputStreams getTmpInputStreams(ExtendedBlock b, long blkoff,
174      long ckoff) throws IOException;
175
176  /**
177   * Creates a temporary replica and returns the meta information of the replica
178   * 
179   * @param b block
180   * @return the meta info of the replica which is being written to
181   * @throws IOException if an error occurs
182   */
183  public ReplicaInPipelineInterface createTemporary(ExtendedBlock b
184      ) throws IOException;
185
186  /**
187   * Creates a RBW replica and returns the meta info of the replica
188   * 
189   * @param b block
190   * @return the meta info of the replica which is being written to
191   * @throws IOException if an error occurs
192   */
193  public ReplicaInPipelineInterface createRbw(ExtendedBlock b
194      ) throws IOException;
195
196  /**
197   * Recovers a RBW replica and returns the meta info of the replica
198   * 
199   * @param b block
200   * @param newGS the new generation stamp for the replica
201   * @param minBytesRcvd the minimum number of bytes that the replica could have
202   * @param maxBytesRcvd the maximum number of bytes that the replica could have
203   * @return the meta info of the replica which is being written to
204   * @throws IOException if an error occurs
205   */
206  public ReplicaInPipelineInterface recoverRbw(ExtendedBlock b, 
207      long newGS, long minBytesRcvd, long maxBytesRcvd) throws IOException;
208
209  /**
210   * Covert a temporary replica to a RBW.
211   * @param temporary the temporary replica being converted
212   * @return the result RBW
213   */
214  public ReplicaInPipelineInterface convertTemporaryToRbw(
215      ExtendedBlock temporary) throws IOException;
216
217  /**
218   * Append to a finalized replica and returns the meta info of the replica
219   * 
220   * @param b block
221   * @param newGS the new generation stamp for the replica
222   * @param expectedBlockLen the number of bytes the replica is expected to have
223   * @return the meata info of the replica which is being written to
224   * @throws IOException
225   */
226  public ReplicaInPipelineInterface append(ExtendedBlock b, long newGS,
227      long expectedBlockLen) throws IOException;
228
229  /**
230   * Recover a failed append to a finalized replica
231   * and returns the meta info of the replica
232   * 
233   * @param b block
234   * @param newGS the new generation stamp for the replica
235   * @param expectedBlockLen the number of bytes the replica is expected to have
236   * @return the meta info of the replica which is being written to
237   * @throws IOException
238   */
239  public ReplicaInPipelineInterface recoverAppend(ExtendedBlock b, long newGS,
240      long expectedBlockLen) throws IOException;
241  
242  /**
243   * Recover a failed pipeline close
244   * It bumps the replica's generation stamp and finalize it if RBW replica
245   * 
246   * @param b block
247   * @param newGS the new generation stamp for the replica
248   * @param expectedBlockLen the number of bytes the replica is expected to have
249   * @return the storage uuid of the replica.
250   * @throws IOException
251   */
252  public String recoverClose(ExtendedBlock b, long newGS, long expectedBlockLen
253      ) throws IOException;
254  
255  /**
256   * Finalizes the block previously opened for writing using writeToBlock.
257   * The block size is what is in the parameter b and it must match the amount
258   *  of data written
259   * @param b
260   * @throws IOException
261   */
262  public void finalizeBlock(ExtendedBlock b) throws IOException;
263
264  /**
265   * Unfinalizes the block previously opened for writing using writeToBlock.
266   * The temporary file associated with this block is deleted.
267   * @param b
268   * @throws IOException
269   */
270  public void unfinalizeBlock(ExtendedBlock b) throws IOException;
271
272  /**
273   * Returns one block report per volume.
274   * @param bpid Block Pool Id
275   * @return - a map of DatanodeStorage to block report for the volume.
276   */
277  public Map<DatanodeStorage, BlockListAsLongs> getBlockReports(String bpid);
278
279  /**
280   * Returns the cache report - the full list of cached block IDs of a
281   * block pool.
282   * @param   bpid Block Pool Id
283   * @return  the cache report - the full list of cached block IDs.
284   */
285  public List<Long> getCacheReport(String bpid);
286
287  /** Does the dataset contain the block? */
288  public boolean contains(ExtendedBlock block);
289
290  /**
291   * Is the block valid?
292   * @param b
293   * @return - true if the specified block is valid
294   */
295  public boolean isValidBlock(ExtendedBlock b);
296
297  /**
298   * Is the block a valid RBW?
299   * @param b
300   * @return - true if the specified block is a valid RBW
301   */
302  public boolean isValidRbw(ExtendedBlock b);
303
304  /**
305   * Invalidates the specified blocks
306   * @param bpid Block pool Id
307   * @param invalidBlks - the blocks to be invalidated
308   * @throws IOException
309   */
310  public void invalidate(String bpid, Block invalidBlks[]) throws IOException;
311
312  /**
313   * Caches the specified blocks
314   * @param bpid Block pool id
315   * @param blockIds - block ids to cache
316   */
317  public void cache(String bpid, long[] blockIds);
318
319  /**
320   * Uncaches the specified blocks
321   * @param bpid Block pool id
322   * @param blockIds - blocks ids to uncache
323   */
324  public void uncache(String bpid, long[] blockIds);
325
326  /**
327   * Determine if the specified block is cached.
328   * @param bpid Block pool id
329   * @param blockIds - block id
330   * @returns true if the block is cached
331   */
332  public boolean isCached(String bpid, long blockId);
333
334    /**
335     * Check if all the data directories are healthy
336     * @throws DiskErrorException
337     */
338  public void checkDataDir() throws DiskErrorException;
339
340  /**
341   * Shutdown the FSDataset
342   */
343  public void shutdown();
344
345  /**
346   * Sets the file pointer of the checksum stream so that the last checksum
347   * will be overwritten
348   * @param b block
349   * @param outs The streams for the data file and checksum file
350   * @param checksumSize number of bytes each checksum has
351   * @throws IOException
352   */
353  public void adjustCrcChannelPosition(ExtendedBlock b,
354      ReplicaOutputStreams outs, int checksumSize) throws IOException;
355
356  /**
357   * Checks how many valid storage volumes there are in the DataNode.
358   * @return true if more than the minimum number of valid volumes are left 
359   * in the FSDataSet.
360   */
361  public boolean hasEnoughResource();
362
363  /**
364   * Get visible length of the specified replica.
365   */
366  long getReplicaVisibleLength(final ExtendedBlock block) throws IOException;
367
368  /**
369   * Initialize a replica recovery.
370   * @return actual state of the replica on this data-node or 
371   * null if data-node does not have the replica.
372   */
373  public ReplicaRecoveryInfo initReplicaRecovery(RecoveringBlock rBlock
374      ) throws IOException;
375
376  /**
377   * Update replica's generation stamp and length and finalize it.
378   * @return the ID of storage that stores the block
379   */
380  public String updateReplicaUnderRecovery(ExtendedBlock oldBlock,
381      long recoveryId, long newLength) throws IOException;
382
383  /**
384   * add new block pool ID
385   * @param bpid Block pool Id
386   * @param conf Configuration
387   */
388  public void addBlockPool(String bpid, Configuration conf) throws IOException;
389  
390  /**
391   * Shutdown and remove the block pool from underlying storage.
392   * @param bpid Block pool Id to be removed
393   */
394  public void shutdownBlockPool(String bpid) ;
395  
396  /**
397   * Deletes the block pool directories. If force is false, directories are 
398   * deleted only if no block files exist for the block pool. If force 
399   * is true entire directory for the blockpool is deleted along with its
400   * contents.
401   * @param bpid BlockPool Id to be deleted.
402   * @param force If force is false, directories are deleted only if no
403   *        block files exist for the block pool, otherwise entire 
404   *        directory for the blockpool is deleted along with its contents.
405   * @throws IOException
406   */
407  public void deleteBlockPool(String bpid, boolean force) throws IOException;
408  
409  /**
410   * Get {@link BlockLocalPathInfo} for the given block.
411   */
412  public BlockLocalPathInfo getBlockLocalPathInfo(ExtendedBlock b
413      ) throws IOException;
414
415  /**
416   * Get a {@link HdfsBlocksMetadata} corresponding to the list of blocks in 
417   * <code>blocks</code>.
418   * 
419   * @param bpid pool to query
420   * @param blockIds List of block ids for which to return metadata
421   * @return metadata Metadata for the list of blocks
422   * @throws IOException
423   */
424  public HdfsBlocksMetadata getHdfsBlocksMetadata(String bpid,
425      long[] blockIds) throws IOException;
426
427  /**
428   * Enable 'trash' for the given dataset. When trash is enabled, files are
429   * moved to a separate trash directory instead of being deleted immediately.
430   * This can be useful for example during rolling upgrades.
431   */
432  public void enableTrash(String bpid);
433
434  /**
435   * Restore trash
436   */
437  public void restoreTrash(String bpid);
438
439  /**
440   * @return true when trash is enabled
441   */
442  public boolean trashEnabled(String bpid);
443}
444