1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.snapshot;
19
20 import java.io.FileNotFoundException;
21 import java.io.IOException;
22 import java.util.Collections;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.hadoop.conf.Configuration;
27 import org.apache.hadoop.fs.FSDataInputStream;
28 import org.apache.hadoop.fs.FSDataOutputStream;
29 import org.apache.hadoop.fs.FileSystem;
30 import org.apache.hadoop.fs.Path;
31 import org.apache.hadoop.fs.permission.FsPermission;
32 import org.apache.hadoop.hbase.HConstants;
33 import org.apache.hadoop.hbase.classification.InterfaceAudience;
34 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
35 import org.apache.hadoop.hbase.security.User;
36 import org.apache.hadoop.hbase.snapshot.SnapshotManifestV2;
37 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
38 import org.apache.hadoop.hbase.util.FSUtils;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 @InterfaceAudience.Private
77 public final class SnapshotDescriptionUtils {
78
79
80
81
82 public static class CompletedSnaphotDirectoriesFilter extends FSUtils.BlackListDirFilter {
83
84
85
86
87 public CompletedSnaphotDirectoriesFilter(FileSystem fs) {
88 super(fs, Collections.singletonList(SNAPSHOT_TMP_DIR_NAME));
89 }
90 }
91
92 private static final Log LOG = LogFactory.getLog(SnapshotDescriptionUtils.class);
93
94
95
96
97 public static final int SNAPSHOT_LAYOUT_VERSION = SnapshotManifestV2.DESCRIPTOR_VERSION;
98
99
100
101
102
103 public static final String SNAPSHOTINFO_FILE = ".snapshotinfo";
104
105
106 public static final String SNAPSHOT_TMP_DIR_NAME = ".tmp";
107
108
109 public static final String SNAPSHOT_IN_PROGRESS = ".inprogress";
110
111
112 public static final long NO_SNAPSHOT_START_TIME_SPECIFIED = 0;
113
114
115 public static final String MASTER_SNAPSHOT_TIMEOUT_MILLIS = "hbase.snapshot.master.timeout.millis";
116
117
118 public static final long DEFAULT_MAX_WAIT_TIME = 60000 * 5 ;
119
120
121
122
123
124
125 @Deprecated
126 public static final int SNAPSHOT_TIMEOUT_MILLIS_DEFAULT = 60000 * 5;
127
128
129
130
131
132
133 @Deprecated
134 public static final String SNAPSHOT_TIMEOUT_MILLIS_KEY = "hbase.snapshot.master.timeoutMillis";
135
136 private SnapshotDescriptionUtils() {
137
138 }
139
140
141
142
143
144
145
146 public static long getMaxMasterTimeout(Configuration conf, SnapshotDescription.Type type,
147 long defaultMaxWaitTime) {
148 String confKey;
149 switch (type) {
150 case DISABLED:
151 default:
152 confKey = MASTER_SNAPSHOT_TIMEOUT_MILLIS;
153 }
154 return Math.max(conf.getLong(confKey, defaultMaxWaitTime),
155 conf.getLong(SNAPSHOT_TIMEOUT_MILLIS_KEY, defaultMaxWaitTime));
156 }
157
158
159
160
161
162
163
164 public static Path getSnapshotRootDir(final Path rootDir) {
165 return new Path(rootDir, HConstants.SNAPSHOT_DIR_NAME);
166 }
167
168
169
170
171
172
173
174
175 public static Path getCompletedSnapshotDir(final SnapshotDescription snapshot, final Path rootDir) {
176 return getCompletedSnapshotDir(snapshot.getName(), rootDir);
177 }
178
179
180
181
182
183
184
185
186 public static Path getCompletedSnapshotDir(final String snapshotName, final Path rootDir) {
187 return getCompletedSnapshotDir(getSnapshotsDir(rootDir), snapshotName);
188 }
189
190
191
192
193
194
195
196 public static Path getWorkingSnapshotDir(final Path rootDir) {
197 return new Path(getSnapshotsDir(rootDir), SNAPSHOT_TMP_DIR_NAME);
198 }
199
200
201
202
203
204
205
206 public static Path getWorkingSnapshotDir(SnapshotDescription snapshot, final Path rootDir) {
207 return getCompletedSnapshotDir(getWorkingSnapshotDir(rootDir), snapshot.getName());
208 }
209
210
211
212
213
214
215
216 public static Path getWorkingSnapshotDir(String snapshotName, final Path rootDir) {
217 return getCompletedSnapshotDir(getWorkingSnapshotDir(rootDir), snapshotName);
218 }
219
220
221
222
223
224
225
226 private static final Path getCompletedSnapshotDir(final Path snapshotsDir, String snapshotName) {
227 return new Path(snapshotsDir, snapshotName);
228 }
229
230
231
232
233
234 public static final Path getSnapshotsDir(Path rootDir) {
235 return new Path(rootDir, HConstants.SNAPSHOT_DIR_NAME);
236 }
237
238
239
240
241
242
243
244
245
246
247
248 public static SnapshotDescription validate(SnapshotDescription snapshot, Configuration conf)
249 throws IllegalArgumentException {
250 if (!snapshot.hasTable()) {
251 throw new IllegalArgumentException(
252 "Descriptor doesn't apply to a table, so we can't build it.");
253 }
254
255
256 long time = snapshot.getCreationTime();
257 if (time == SnapshotDescriptionUtils.NO_SNAPSHOT_START_TIME_SPECIFIED) {
258 time = EnvironmentEdgeManager.currentTime();
259 LOG.debug("Creation time not specified, setting to:" + time + " (current time:"
260 + EnvironmentEdgeManager.currentTime() + ").");
261 SnapshotDescription.Builder builder = snapshot.toBuilder();
262 builder.setCreationTime(time);
263 snapshot = builder.build();
264 }
265 return snapshot;
266 }
267
268
269
270
271
272
273
274
275
276 public static void writeSnapshotInfo(SnapshotDescription snapshot, Path workingDir, FileSystem fs)
277 throws IOException {
278 FsPermission perms = FSUtils.getFilePermissions(fs, fs.getConf(),
279 HConstants.DATA_FILE_UMASK_KEY);
280 Path snapshotInfo = new Path(workingDir, SnapshotDescriptionUtils.SNAPSHOTINFO_FILE);
281 try {
282 FSDataOutputStream out = FSUtils.create(fs, snapshotInfo, perms, true);
283 try {
284 snapshot.writeTo(out);
285 } finally {
286 out.close();
287 }
288 } catch (IOException e) {
289
290 if (!fs.delete(snapshotInfo, false)) {
291 String msg = "Couldn't delete snapshot info file: " + snapshotInfo;
292 LOG.error(msg);
293 throw new IOException(msg);
294 }
295 }
296 }
297
298
299
300
301 public static void createInProgressTag(Path workingDir, FileSystem fs) throws IOException {
302 FsPermission perms = FSUtils.getFilePermissions(fs, fs.getConf(),
303 HConstants.DATA_FILE_UMASK_KEY);
304 Path snapshot_in_progress = new Path(workingDir, SnapshotDescriptionUtils.SNAPSHOT_IN_PROGRESS);
305 FSUtils.create(fs, snapshot_in_progress, perms, true);
306 }
307
308
309
310
311
312
313
314
315
316 public static SnapshotDescription readSnapshotInfo(FileSystem fs, Path snapshotDir)
317 throws CorruptedSnapshotException {
318 Path snapshotInfo = new Path(snapshotDir, SNAPSHOTINFO_FILE);
319 try {
320 FSDataInputStream in = null;
321 try {
322 in = fs.open(snapshotInfo);
323 SnapshotDescription desc = SnapshotDescription.parseFrom(in);
324 return desc;
325 } finally {
326 if (in != null) in.close();
327 }
328 } catch (IOException e) {
329 throw new CorruptedSnapshotException("Couldn't read snapshot info from:" + snapshotInfo, e);
330 }
331 }
332
333
334
335
336
337
338
339
340
341
342
343
344 public static void completeSnapshot(SnapshotDescription snapshot, Path rootdir, Path workingDir,
345 FileSystem fs) throws SnapshotCreationException, IOException {
346 Path finishedDir = getCompletedSnapshotDir(snapshot, rootdir);
347 LOG.debug("Snapshot is done, just moving the snapshot from " + workingDir + " to "
348 + finishedDir);
349 if (!fs.rename(workingDir, finishedDir)) {
350 throw new SnapshotCreationException("Failed to move working directory(" + workingDir
351 + ") to completed directory(" + finishedDir + ").", snapshot);
352 }
353 }
354
355
356
357
358
359
360
361
362 public static boolean isSnapshotOwner(final SnapshotDescription snapshot, final User user) {
363 if (user == null) return false;
364 if (!snapshot.hasOwner()) return false;
365 return snapshot.getOwner().equals(user.getShortName());
366 }
367 }