1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  package org.apache.hadoop.hbase.regionserver;
21  
22  import java.io.FileNotFoundException;
23  import java.io.IOException;
24  import java.io.InterruptedIOException;
25  import java.util.ArrayList;
26  import java.util.Collection;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.UUID;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.apache.hadoop.hbase.classification.InterfaceAudience;
34  import org.apache.hadoop.conf.Configuration;
35  import org.apache.hadoop.fs.FSDataInputStream;
36  import org.apache.hadoop.fs.FSDataOutputStream;
37  import org.apache.hadoop.fs.FileStatus;
38  import org.apache.hadoop.fs.FileSystem;
39  import org.apache.hadoop.fs.FileUtil;
40  import org.apache.hadoop.fs.Path;
41  import org.apache.hadoop.fs.permission.FsPermission;
42  import org.apache.hadoop.hbase.HColumnDescriptor;
43  import org.apache.hadoop.hbase.HConstants;
44  import org.apache.hadoop.hbase.HRegionInfo;
45  import org.apache.hadoop.hbase.HTableDescriptor;
46  import org.apache.hadoop.hbase.KeyValue;
47  import org.apache.hadoop.hbase.KeyValueUtil;
48  import org.apache.hadoop.hbase.backup.HFileArchiver;
49  import org.apache.hadoop.hbase.fs.HFileSystem;
50  import org.apache.hadoop.hbase.io.Reference;
51  import org.apache.hadoop.hbase.util.Bytes;
52  import org.apache.hadoop.hbase.util.FSHDFSUtils;
53  import org.apache.hadoop.hbase.util.FSUtils;
54  import org.apache.hadoop.hbase.util.ServerRegionReplicaUtil;
55  
56  
57  
58  
59  
60  @InterfaceAudience.Private
61  public class HRegionFileSystem {
62    public static final Log LOG = LogFactory.getLog(HRegionFileSystem.class);
63  
64    
65    public final static String REGION_INFO_FILE = ".regioninfo";
66  
67    
68    public static final String REGION_MERGES_DIR = ".merges";
69  
70    
71    public static final String REGION_SPLITS_DIR = ".splits";
72  
73    
74    private static final String REGION_TEMP_DIR = ".tmp";
75  
76    private final HRegionInfo regionInfo;
77    
78    private final HRegionInfo regionInfoForFs;
79    private final Configuration conf;
80    private final Path tableDir;
81    private final FileSystem fs;
82  
83    
84  
85  
86  
87    private final int hdfsClientRetriesNumber;
88    private final int baseSleepBeforeRetries;
89    private static final int DEFAULT_HDFS_CLIENT_RETRIES_NUMBER = 10;
90    private static final int DEFAULT_BASE_SLEEP_BEFORE_RETRIES = 1000;
91  
92    
93  
94  
95  
96  
97  
98  
99    HRegionFileSystem(final Configuration conf, final FileSystem fs, final Path tableDir,
100       final HRegionInfo regionInfo) {
101     this.fs = fs;
102     this.conf = conf;
103     this.tableDir = tableDir;
104     this.regionInfo = regionInfo;
105     this.regionInfoForFs = ServerRegionReplicaUtil.getRegionInfoForFs(regionInfo);
106     this.hdfsClientRetriesNumber = conf.getInt("hdfs.client.retries.number",
107       DEFAULT_HDFS_CLIENT_RETRIES_NUMBER);
108     this.baseSleepBeforeRetries = conf.getInt("hdfs.client.sleep.before.retries",
109       DEFAULT_BASE_SLEEP_BEFORE_RETRIES);
110  }
111 
112   
113   public FileSystem getFileSystem() {
114     return this.fs;
115   }
116 
117   
118   public HRegionInfo getRegionInfo() {
119     return this.regionInfo;
120   }
121 
122   public HRegionInfo getRegionInfoForFS() {
123     return this.regionInfoForFs;
124   }
125 
126   
127   public Path getTableDir() {
128     return this.tableDir;
129   }
130 
131   
132   public Path getRegionDir() {
133     return new Path(this.tableDir, this.regionInfoForFs.getEncodedName());
134   }
135 
136   
137   
138   
139   
140   Path getTempDir() {
141     return new Path(getRegionDir(), REGION_TEMP_DIR);
142   }
143 
144   
145 
146 
147   void cleanupTempDir() throws IOException {
148     deleteDir(getTempDir());
149   }
150 
151   
152   
153   
154   
155 
156 
157 
158 
159   public Path getStoreDir(final String familyName) {
160     return new Path(this.getRegionDir(), familyName);
161   }
162 
163   
164 
165 
166 
167 
168 
169   Path createStoreDir(final String familyName) throws IOException {
170     Path storeDir = getStoreDir(familyName);
171     if(!fs.exists(storeDir) && !createDir(storeDir))
172       throw new IOException("Failed creating "+storeDir);
173     return storeDir;
174   }
175 
176   
177 
178 
179 
180 
181 
182   public Collection<StoreFileInfo> getStoreFiles(final byte[] familyName) throws IOException {
183     return getStoreFiles(Bytes.toString(familyName));
184   }
185 
186   public Collection<StoreFileInfo> getStoreFiles(final String familyName) throws IOException {
187     return getStoreFiles(familyName, true);
188   }
189 
190   
191 
192 
193 
194 
195 
196   public Collection<StoreFileInfo> getStoreFiles(final String familyName, final boolean validate)
197       throws IOException {
198     Path familyDir = getStoreDir(familyName);
199     FileStatus[] files = FSUtils.listStatus(this.fs, familyDir);
200     if (files == null) {
201       LOG.debug("No StoreFiles for: " + familyDir);
202       return null;
203     }
204 
205     ArrayList<StoreFileInfo> storeFiles = new ArrayList<StoreFileInfo>(files.length);
206     for (FileStatus status: files) {
207       if (validate && !StoreFileInfo.isValid(status)) {
208         LOG.warn("Invalid StoreFile: " + status.getPath());
209         continue;
210       }
211       StoreFileInfo info = ServerRegionReplicaUtil.getStoreFileInfo(conf, fs, regionInfo,
212         regionInfoForFs, familyName, status.getPath());
213       storeFiles.add(info);
214 
215     }
216     return storeFiles;
217   }
218 
219   
220 
221 
222 
223 
224 
225 
226   Path getStoreFilePath(final String familyName, final String fileName) {
227     Path familyDir = getStoreDir(familyName);
228     return new Path(familyDir, fileName).makeQualified(this.fs);
229   }
230 
231   
232 
233 
234 
235 
236 
237 
238   StoreFileInfo getStoreFileInfo(final String familyName, final String fileName)
239       throws IOException {
240     Path familyDir = getStoreDir(familyName);
241     return ServerRegionReplicaUtil.getStoreFileInfo(conf, fs, regionInfo,
242       regionInfoForFs, familyName, new Path(familyDir, fileName));
243   }
244 
245   
246 
247 
248 
249 
250 
251   public boolean hasReferences(final String familyName) throws IOException {
252     FileStatus[] files = FSUtils.listStatus(fs, getStoreDir(familyName));
253     if (files != null) {
254       for(FileStatus stat: files) {
255         if(stat.isDirectory()) {
256           continue;
257         }
258         if(StoreFileInfo.isReference(stat.getPath())) {
259           return true;
260         }
261       }
262     }
263     return false;
264   }
265 
266   
267 
268 
269 
270 
271 
272   public boolean hasReferences(final HTableDescriptor htd) throws IOException {
273     for (HColumnDescriptor family : htd.getFamilies()) {
274       if (hasReferences(family.getNameAsString())) {
275         return true;
276       }
277     }
278     return false;
279   }
280 
281   
282 
283 
284 
285   public Collection<String> getFamilies() throws IOException {
286     FileStatus[] fds = FSUtils.listStatus(fs, getRegionDir(), new FSUtils.FamilyDirFilter(fs));
287     if (fds == null) return null;
288 
289     ArrayList<String> families = new ArrayList<String>(fds.length);
290     for (FileStatus status: fds) {
291       families.add(status.getPath().getName());
292     }
293 
294     return families;
295   }
296 
297   
298 
299 
300 
301 
302   public void deleteFamily(final String familyName) throws IOException {
303     
304     HFileArchiver.archiveFamily(fs, conf, regionInfoForFs, tableDir, Bytes.toBytes(familyName));
305 
306     
307     Path familyDir = getStoreDir(familyName);
308     if(fs.exists(familyDir) && !deleteDir(familyDir))
309       throw new IOException("Could not delete family " + familyName
310           + " from FileSystem for region " + regionInfoForFs.getRegionNameAsString() + "("
311           + regionInfoForFs.getEncodedName() + ")");
312   }
313 
314   
315 
316 
317 
318 
319   private static String generateUniqueName(final String suffix) {
320     String name = UUID.randomUUID().toString().replaceAll("-", "");
321     if (suffix != null) name += suffix;
322     return name;
323   }
324 
325   
326 
327 
328 
329 
330 
331 
332 
333 
334 
335 
336   public Path createTempName() {
337     return createTempName(null);
338   }
339 
340   
341 
342 
343 
344 
345 
346 
347 
348 
349 
350 
351 
352   public Path createTempName(final String suffix) {
353     return new Path(getTempDir(), generateUniqueName(suffix));
354   }
355 
356   
357 
358 
359 
360 
361 
362 
363   public Path commitStoreFile(final String familyName, final Path buildPath) throws IOException {
364     return commitStoreFile(familyName, buildPath, -1, false);
365   }
366 
367   
368 
369 
370 
371 
372 
373 
374 
375 
376   private Path commitStoreFile(final String familyName, final Path buildPath,
377       final long seqNum, final boolean generateNewName) throws IOException {
378     Path storeDir = getStoreDir(familyName);
379     if(!fs.exists(storeDir) && !createDir(storeDir))
380       throw new IOException("Failed creating " + storeDir);
381 
382     String name = buildPath.getName();
383     if (generateNewName) {
384       name = generateUniqueName((seqNum < 0) ? null : "_SeqId_" + seqNum + "_");
385     }
386     Path dstPath = new Path(storeDir, name);
387     if (!fs.exists(buildPath)) {
388       throw new FileNotFoundException(buildPath.toString());
389     }
390     LOG.debug("Committing store file " + buildPath + " as " + dstPath);
391     
392     if (!rename(buildPath, dstPath)) {
393       throw new IOException("Failed rename of " + buildPath + " to " + dstPath);
394     }
395     return dstPath;
396   }
397 
398 
399   
400 
401 
402 
403 
404   void commitStoreFiles(final Map<byte[], List<StoreFile>> storeFiles) throws IOException {
405     for (Map.Entry<byte[], List<StoreFile>> es: storeFiles.entrySet()) {
406       String familyName = Bytes.toString(es.getKey());
407       for (StoreFile sf: es.getValue()) {
408         commitStoreFile(familyName, sf.getPath());
409       }
410     }
411   }
412 
413   
414 
415 
416 
417 
418 
419   public void removeStoreFile(final String familyName, final Path filePath)
420       throws IOException {
421     HFileArchiver.archiveStoreFile(this.conf, this.fs, this.regionInfoForFs,
422         this.tableDir, Bytes.toBytes(familyName), filePath);
423   }
424 
425   
426 
427 
428 
429 
430 
431   public void removeStoreFiles(final String familyName, final Collection<StoreFile> storeFiles)
432       throws IOException {
433     HFileArchiver.archiveStoreFiles(this.conf, this.fs, this.regionInfoForFs,
434         this.tableDir, Bytes.toBytes(familyName), storeFiles);
435   }
436 
437   
438 
439 
440 
441 
442 
443 
444 
445 
446 
447 
448   Path bulkLoadStoreFile(final String familyName, Path srcPath, long seqNum)
449       throws IOException {
450     
451     FileSystem srcFs = srcPath.getFileSystem(conf);
452     FileSystem desFs = fs instanceof HFileSystem ? ((HFileSystem)fs).getBackingFs() : fs;
453 
454     
455     
456     
457     if (!FSHDFSUtils.isSameHdfs(conf, srcFs, desFs)) {
458       LOG.info("Bulk-load file " + srcPath + " is on different filesystem than " +
459           "the destination store. Copying file over to destination filesystem.");
460       Path tmpPath = createTempName();
461       FileUtil.copy(srcFs, srcPath, fs, tmpPath, false, conf);
462       LOG.info("Copied " + srcPath + " to temporary path on destination filesystem: " + tmpPath);
463       srcPath = tmpPath;
464     }
465 
466     return commitStoreFile(familyName, srcPath, seqNum, true);
467   }
468 
469   
470   
471   
472   
473   Path getSplitsDir() {
474     return new Path(getRegionDir(), REGION_SPLITS_DIR);
475   }
476 
477   Path getSplitsDir(final HRegionInfo hri) {
478     return new Path(getSplitsDir(), hri.getEncodedName());
479   }
480 
481   
482 
483 
484   void cleanupSplitsDir() throws IOException {
485     deleteDir(getSplitsDir());
486   }
487 
488   
489 
490 
491 
492 
493 
494   void cleanupAnySplitDetritus() throws IOException {
495     Path splitdir = this.getSplitsDir();
496     if (!fs.exists(splitdir)) return;
497     
498     
499     
500     
501     
502     
503     
504     FileStatus[] daughters = FSUtils.listStatus(fs, splitdir, new FSUtils.DirFilter(fs));
505     if (daughters != null) {
506       for (FileStatus daughter: daughters) {
507         Path daughterDir = new Path(getTableDir(), daughter.getPath().getName());
508         if (fs.exists(daughterDir) && !deleteDir(daughterDir)) {
509           throw new IOException("Failed delete of " + daughterDir);
510         }
511       }
512     }
513     cleanupSplitsDir();
514     LOG.info("Cleaned up old failed split transaction detritus: " + splitdir);
515   }
516 
517   
518 
519 
520 
521 
522   void cleanupDaughterRegion(final HRegionInfo regionInfo) throws IOException {
523     Path regionDir = new Path(this.tableDir, regionInfo.getEncodedName());
524     if (this.fs.exists(regionDir) && !deleteDir(regionDir)) {
525       throw new IOException("Failed delete of " + regionDir);
526     }
527   }
528 
529   
530 
531 
532 
533 
534 
535 
536   Path commitDaughterRegion(final HRegionInfo regionInfo)
537       throws IOException {
538     Path regionDir = new Path(this.tableDir, regionInfo.getEncodedName());
539     Path daughterTmpDir = this.getSplitsDir(regionInfo);
540 
541     if (fs.exists(daughterTmpDir)) {
542 
543       
544       Path regionInfoFile = new Path(daughterTmpDir, REGION_INFO_FILE);
545       byte[] regionInfoContent = getRegionInfoFileContent(regionInfo);
546       writeRegionInfoFileContent(conf, fs, regionInfoFile, regionInfoContent);
547 
548       
549       if (!rename(daughterTmpDir, regionDir)) {
550         throw new IOException("Unable to rename " + daughterTmpDir + " to " + regionDir);
551       }
552     }
553 
554     return regionDir;
555   }
556 
557   
558 
559 
560   void createSplitsDir() throws IOException {
561     Path splitdir = getSplitsDir();
562     if (fs.exists(splitdir)) {
563       LOG.info("The " + splitdir + " directory exists.  Hence deleting it to recreate it");
564       if (!deleteDir(splitdir)) {
565         throw new IOException("Failed deletion of " + splitdir
566             + " before creating them again.");
567       }
568     }
569     
570     if (!createDir(splitdir)) {
571       throw new IOException("Failed create of " + splitdir);
572     }
573   }
574 
575   
576 
577 
578 
579 
580 
581 
582 
583 
584 
585 
586 
587   Path splitStoreFile(final HRegionInfo hri, final String familyName, final StoreFile f,
588       final byte[] splitRow, final boolean top, RegionSplitPolicy splitPolicy) throws IOException {
589 
590     if (splitPolicy == null || !splitPolicy.skipStoreFileRangeCheck(familyName)) {
591       
592       
593       try {
594         if (top) {
595           
596           KeyValue splitKey = KeyValueUtil.createFirstOnRow(splitRow);
597           byte[] lastKey = f.getLastKey();
598           
599           if (lastKey == null) {
600             return null;
601           }
602           if (f.getComparator().compareFlatKey(splitKey.getBuffer(),
603             splitKey.getKeyOffset(), splitKey.getKeyLength(), lastKey, 0, lastKey.length) > 0) {
604             return null;
605           }
606         } else {
607           
608           KeyValue splitKey = KeyValueUtil.createLastOnRow(splitRow);
609           byte[] firstKey = f.getFirstKey();
610           
611           if (firstKey == null) {
612             return null;
613           }
614           if (f.getComparator().compareFlatKey(splitKey.getBuffer(),
615             splitKey.getKeyOffset(), splitKey.getKeyLength(), firstKey, 0, firstKey.length) < 0) {
616             return null;
617           }
618         }
619       } finally {
620         f.closeReader(true);
621       }
622     }
623 
624     Path splitDir = new Path(getSplitsDir(hri), familyName);
625     
626     Reference r =
627       top ? Reference.createTopReference(splitRow): Reference.createBottomReference(splitRow);
628     
629     
630     
631     
632     String parentRegionName = regionInfoForFs.getEncodedName();
633     
634     
635     Path p = new Path(splitDir, f.getPath().getName() + "." + parentRegionName);
636     return r.write(fs, p);
637   }
638 
639   
640   
641   
642   
643   Path getMergesDir() {
644     return new Path(getRegionDir(), REGION_MERGES_DIR);
645   }
646 
647   Path getMergesDir(final HRegionInfo hri) {
648     return new Path(getMergesDir(), hri.getEncodedName());
649   }
650 
651   
652 
653 
654   void cleanupMergesDir() throws IOException {
655     deleteDir(getMergesDir());
656   }
657 
658   
659 
660 
661 
662 
663   void cleanupMergedRegion(final HRegionInfo mergedRegion) throws IOException {
664     Path regionDir = new Path(this.tableDir, mergedRegion.getEncodedName());
665     if (this.fs.exists(regionDir) && !this.fs.delete(regionDir, true)) {
666       throw new IOException("Failed delete of " + regionDir);
667     }
668   }
669 
670   
671 
672 
673 
674 
675   void createMergesDir() throws IOException {
676     Path mergesdir = getMergesDir();
677     if (fs.exists(mergesdir)) {
678       LOG.info("The " + mergesdir
679           + " directory exists.  Hence deleting it to recreate it");
680       if (!fs.delete(mergesdir, true)) {
681         throw new IOException("Failed deletion of " + mergesdir
682             + " before creating them again.");
683       }
684     }
685     if (!fs.mkdirs(mergesdir))
686       throw new IOException("Failed create of " + mergesdir);
687   }
688 
689   
690 
691 
692 
693 
694 
695 
696 
697 
698 
699   Path mergeStoreFile(final HRegionInfo mergedRegion, final String familyName,
700       final StoreFile f, final Path mergedDir)
701       throws IOException {
702     Path referenceDir = new Path(new Path(mergedDir,
703         mergedRegion.getEncodedName()), familyName);
704     
705     Reference r = Reference.createTopReference(regionInfoForFs.getStartKey());
706     
707     
708     
709     
710     String mergingRegionName = regionInfoForFs.getEncodedName();
711     
712     
713     Path p = new Path(referenceDir, f.getPath().getName() + "."
714         + mergingRegionName);
715     return r.write(fs, p);
716   }
717 
718   
719 
720 
721 
722 
723 
724   void commitMergedRegion(final HRegionInfo mergedRegionInfo) throws IOException {
725     Path regionDir = new Path(this.tableDir, mergedRegionInfo.getEncodedName());
726     Path mergedRegionTmpDir = this.getMergesDir(mergedRegionInfo);
727     
728     if (mergedRegionTmpDir != null && fs.exists(mergedRegionTmpDir)) {
729       if (!fs.rename(mergedRegionTmpDir, regionDir)) {
730         throw new IOException("Unable to rename " + mergedRegionTmpDir + " to "
731             + regionDir);
732       }
733     }
734   }
735 
736   
737   
738   
739   
740 
741 
742 
743 
744   void logFileSystemState(final Log LOG) throws IOException {
745     FSUtils.logFileSystemState(fs, this.getRegionDir(), LOG);
746   }
747 
748   
749 
750 
751 
752 
753   private static byte[] getRegionInfoFileContent(final HRegionInfo hri) throws IOException {
754     return hri.toDelimitedByteArray();
755   }
756 
757   
758 
759 
760 
761 
762 
763 
764   public static HRegionInfo loadRegionInfoFileContent(final FileSystem fs, final Path regionDir)
765       throws IOException {
766     FSDataInputStream in = fs.open(new Path(regionDir, REGION_INFO_FILE));
767     try {
768       return HRegionInfo.parseFrom(in);
769     } finally {
770       in.close();
771     }
772   }
773 
774   
775 
776 
777   private static void writeRegionInfoFileContent(final Configuration conf, final FileSystem fs,
778       final Path regionInfoFile, final byte[] content) throws IOException {
779     
780     FsPermission perms = FSUtils.getFilePermissions(fs, conf, HConstants.DATA_FILE_UMASK_KEY);
781     
782     FSDataOutputStream out = FSUtils.create(fs, regionInfoFile, perms, null);
783     try {
784       out.write(content);
785     } finally {
786       out.close();
787     }
788   }
789 
790   
791 
792 
793 
794   void checkRegionInfoOnFilesystem() throws IOException {
795     
796     
797     
798     
799     
800     byte[] content = getRegionInfoFileContent(regionInfoForFs);
801     try {
802       Path regionInfoFile = new Path(getRegionDir(), REGION_INFO_FILE);
803 
804       FileStatus status = fs.getFileStatus(regionInfoFile);
805       if (status != null && status.getLen() == content.length) {
806         
807         
808         return;
809       }
810 
811       LOG.info("Rewriting .regioninfo file at: " + regionInfoFile);
812       if (!fs.delete(regionInfoFile, false)) {
813         throw new IOException("Unable to remove existing " + regionInfoFile);
814       }
815     } catch (FileNotFoundException e) {
816       LOG.warn(REGION_INFO_FILE + " file not found for region: " + regionInfoForFs.getEncodedName() +
817           " on table " + regionInfo.getTable());
818     }
819 
820     
821     writeRegionInfoOnFilesystem(content, true);
822   }
823 
824   
825 
826 
827 
828   private void writeRegionInfoOnFilesystem(boolean useTempDir) throws IOException {
829     byte[] content = getRegionInfoFileContent(regionInfoForFs);
830     writeRegionInfoOnFilesystem(content, useTempDir);
831   }
832 
833   
834 
835 
836 
837 
838   private void writeRegionInfoOnFilesystem(final byte[] regionInfoContent,
839       final boolean useTempDir) throws IOException {
840     Path regionInfoFile = new Path(getRegionDir(), REGION_INFO_FILE);
841     if (useTempDir) {
842       
843       
844       
845       
846 
847       
848       Path tmpPath = new Path(getTempDir(), REGION_INFO_FILE);
849 
850       
851       
852       
853       
854       if (FSUtils.isExists(fs, tmpPath)) {
855         FSUtils.delete(fs, tmpPath, true);
856       }
857 
858       
859       writeRegionInfoFileContent(conf, fs, tmpPath, regionInfoContent);
860 
861       
862       if (fs.exists(tmpPath) &&  !rename(tmpPath, regionInfoFile)) {
863         throw new IOException("Unable to rename " + tmpPath + " to " + regionInfoFile);
864       }
865     } else {
866       
867       writeRegionInfoFileContent(conf, fs, regionInfoFile, regionInfoContent);
868     }
869   }
870 
871   
872 
873 
874 
875 
876 
877 
878 
879   public static HRegionFileSystem createRegionOnFileSystem(final Configuration conf,
880       final FileSystem fs, final Path tableDir, final HRegionInfo regionInfo) throws IOException {
881     HRegionFileSystem regionFs = new HRegionFileSystem(conf, fs, tableDir, regionInfo);
882     Path regionDir = regionFs.getRegionDir();
883 
884     if (fs.exists(regionDir)) {
885       LOG.warn("Trying to create a region that already exists on disk: " + regionDir);
886       throw new IOException("The specified region already exists on disk: " + regionDir);
887     }
888 
889     
890     if (!createDirOnFileSystem(fs, conf, regionDir)) {
891       LOG.warn("Unable to create the region directory: " + regionDir);
892       throw new IOException("Unable to create region directory: " + regionDir);
893     }
894 
895     
896     regionFs.writeRegionInfoOnFilesystem(false);
897     return regionFs;
898   }
899 
900   
901 
902 
903 
904 
905 
906 
907 
908 
909   public static HRegionFileSystem openRegionFromFileSystem(final Configuration conf,
910       final FileSystem fs, final Path tableDir, final HRegionInfo regionInfo, boolean readOnly)
911       throws IOException {
912     HRegionFileSystem regionFs = new HRegionFileSystem(conf, fs, tableDir, regionInfo);
913     Path regionDir = regionFs.getRegionDir();
914 
915     if (!fs.exists(regionDir)) {
916       LOG.warn("Trying to open a region that do not exists on disk: " + regionDir);
917       throw new IOException("The specified region do not exists on disk: " + regionDir);
918     }
919 
920     if (!readOnly) {
921       
922       regionFs.cleanupTempDir();
923       regionFs.cleanupSplitsDir();
924       regionFs.cleanupMergesDir();
925 
926       
927       regionFs.checkRegionInfoOnFilesystem();
928     }
929 
930     return regionFs;
931   }
932 
933   
934 
935 
936 
937 
938 
939 
940 
941   public static void deleteRegionFromFileSystem(final Configuration conf,
942       final FileSystem fs, final Path tableDir, final HRegionInfo regionInfo) throws IOException {
943     HRegionFileSystem regionFs = new HRegionFileSystem(conf, fs, tableDir, regionInfo);
944     Path regionDir = regionFs.getRegionDir();
945 
946     if (!fs.exists(regionDir)) {
947       LOG.warn("Trying to delete a region that do not exists on disk: " + regionDir);
948       return;
949     }
950 
951     if (LOG.isDebugEnabled()) {
952       LOG.debug("DELETING region " + regionDir);
953     }
954 
955     
956     Path rootDir = FSUtils.getRootDir(conf);
957     HFileArchiver.archiveRegion(fs, rootDir, tableDir, regionDir);
958 
959     
960     if (!fs.delete(regionDir, true)) {
961       LOG.warn("Failed delete of " + regionDir);
962     }
963   }
964 
965   
966 
967 
968 
969 
970 
971 
972   boolean createDir(Path dir) throws IOException {
973     int i = 0;
974     IOException lastIOE = null;
975     do {
976       try {
977         return fs.mkdirs(dir);
978       } catch (IOException ioe) {
979         lastIOE = ioe;
980         if (fs.exists(dir)) return true; 
981         try {
982           sleepBeforeRetry("Create Directory", i+1);
983         } catch (InterruptedException e) {
984           throw (InterruptedIOException)new InterruptedIOException().initCause(e);
985         }
986       }
987     } while (++i <= hdfsClientRetriesNumber);
988     throw new IOException("Exception in createDir", lastIOE);
989   }
990 
991   
992 
993 
994 
995 
996 
997 
998   boolean rename(Path srcpath, Path dstPath) throws IOException {
999     IOException lastIOE = null;
1000     int i = 0;
1001     do {
1002       try {
1003         return fs.rename(srcpath, dstPath);
1004       } catch (IOException ioe) {
1005         lastIOE = ioe;
1006         if (!fs.exists(srcpath) && fs.exists(dstPath)) return true; 
1007         
1008         try {
1009           sleepBeforeRetry("Rename Directory", i+1);
1010         } catch (InterruptedException e) {
1011           throw (InterruptedIOException)new InterruptedIOException().initCause(e);
1012         }
1013       }
1014     } while (++i <= hdfsClientRetriesNumber);
1015 
1016     throw new IOException("Exception in rename", lastIOE);
1017   }
1018 
1019   
1020 
1021 
1022 
1023 
1024 
1025   boolean deleteDir(Path dir) throws IOException {
1026     IOException lastIOE = null;
1027     int i = 0;
1028     do {
1029       try {
1030         return fs.delete(dir, true);
1031       } catch (IOException ioe) {
1032         lastIOE = ioe;
1033         if (!fs.exists(dir)) return true;
1034         
1035         try {
1036           sleepBeforeRetry("Delete Directory", i+1);
1037         } catch (InterruptedException e) {
1038           throw (InterruptedIOException)new InterruptedIOException().initCause(e);
1039         }
1040       }
1041     } while (++i <= hdfsClientRetriesNumber);
1042 
1043     throw new IOException("Exception in DeleteDir", lastIOE);
1044   }
1045 
1046   
1047 
1048 
1049   private void sleepBeforeRetry(String msg, int sleepMultiplier) throws InterruptedException {
1050     sleepBeforeRetry(msg, sleepMultiplier, baseSleepBeforeRetries, hdfsClientRetriesNumber);
1051   }
1052 
1053   
1054 
1055 
1056 
1057 
1058 
1059 
1060 
1061 
1062 
1063   private static boolean createDirOnFileSystem(FileSystem fs, Configuration conf, Path dir)
1064       throws IOException {
1065     int i = 0;
1066     IOException lastIOE = null;
1067     int hdfsClientRetriesNumber = conf.getInt("hdfs.client.retries.number",
1068       DEFAULT_HDFS_CLIENT_RETRIES_NUMBER);
1069     int baseSleepBeforeRetries = conf.getInt("hdfs.client.sleep.before.retries",
1070       DEFAULT_BASE_SLEEP_BEFORE_RETRIES);
1071     do {
1072       try {
1073         return fs.mkdirs(dir);
1074       } catch (IOException ioe) {
1075         lastIOE = ioe;
1076         if (fs.exists(dir)) return true; 
1077         try {
1078           sleepBeforeRetry("Create Directory", i+1, baseSleepBeforeRetries, hdfsClientRetriesNumber);
1079         } catch (InterruptedException e) {
1080           throw (InterruptedIOException)new InterruptedIOException().initCause(e);
1081         }
1082       }
1083     } while (++i <= hdfsClientRetriesNumber);
1084 
1085     throw new IOException("Exception in createDir", lastIOE);
1086   }
1087 
1088   
1089 
1090 
1091 
1092   private static void sleepBeforeRetry(String msg, int sleepMultiplier, int baseSleepBeforeRetries,
1093       int hdfsClientRetriesNumber) throws InterruptedException {
1094     if (sleepMultiplier > hdfsClientRetriesNumber) {
1095       LOG.debug(msg + ", retries exhausted");
1096       return;
1097     }
1098     LOG.debug(msg + ", sleeping " + baseSleepBeforeRetries + " times " + sleepMultiplier);
1099     Thread.sleep((long)baseSleepBeforeRetries * sleepMultiplier);
1100   }
1101 }