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
19 package org.apache.hadoop.fs;
20
21 import java.io;
22 import java.net.URI;
23 import java.util;
24
25 /****************************************************************
26 * Implement the FileSystem API for the checksumed local filesystem.
27 *
28 *****************************************************************/
29 public class LocalFileSystem extends ChecksumFileSystem {
30 static final URI NAME = URI.create("file:///");
31 static private Random rand = new Random();
32
33 public LocalFileSystem() {
34 super(new RawLocalFileSystem());
35 }
36
37 public LocalFileSystem(FileSystem rawLocalFileSystem) {
38 super(rawLocalFileSystem);
39 }
40
41 /** Convert a path to a File. */
42 public File pathToFile(Path path) {
43 return ((RawLocalFileSystem)fs).pathToFile(path);
44 }
45
46 @Override
47 public void copyFromLocalFile(boolean delSrc, Path src, Path dst)
48 throws IOException {
49 FileUtil.copy(this, src, this, dst, delSrc, getConf());
50 }
51
52 @Override
53 public void copyToLocalFile(boolean delSrc, Path src, Path dst)
54 throws IOException {
55 FileUtil.copy(this, src, this, dst, delSrc, getConf());
56 }
57
58 /**
59 * Moves files to a bad file directory on the same device, so that their
60 * storage will not be reused.
61 */
62 public boolean reportChecksumFailure(Path p, FSDataInputStream in,
63 long inPos,
64 FSDataInputStream sums, long sumsPos) {
65 try {
66 // canonicalize f
67 File f = ((RawLocalFileSystem)fs).pathToFile(p).getCanonicalFile();
68
69 // find highest writable parent dir of f on the same device
70 String device = new DF(f, getConf()).getMount();
71 File parent = f.getParentFile();
72 File dir = null;
73 while (parent!=null && parent.canWrite() && parent.toString().startsWith(device)) {
74 dir = parent;
75 parent = parent.getParentFile();
76 }
77
78 if (dir==null) {
79 throw new IOException(
80 "not able to find the highest writable parent dir");
81 }
82
83 // move the file there
84 File badDir = new File(dir, "bad_files");
85 if (!badDir.mkdirs()) {
86 if (!badDir.isDirectory()) {
87 throw new IOException("Mkdirs failed to create " + badDir.toString());
88 }
89 }
90 String suffix = "." + rand.nextInt();
91 File badFile = new File(badDir, f.getName()+suffix);
92 LOG.warn("Moving bad file " + f + " to " + badFile);
93 in.close(); // close it first
94 f.renameTo(badFile); // rename it
95
96 // move checksum file too
97 File checkFile = ((RawLocalFileSystem)fs).pathToFile(getChecksumFile(p));
98 checkFile.renameTo(new File(badDir, checkFile.getName()+suffix));
99
100 } catch (IOException e) {
101 LOG.warn("Error moving bad file " + p + ": " + e);
102 }
103 return false;
104 }
105 }