From 3131e49840d0aeca2d58a486192778485af8c866 Mon Sep 17 00:00:00 2001 From: Daryn Sharp Date: Tue, 3 Jul 2012 20:28:30 +0000 Subject: [PATCH] HADOOP-8110. Fix trash checkpoint collisions (Jason Lowe via daryn) git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1356918 13f79535-47bb-0310-9956-ffa450edef68 --- .../hadoop-common/CHANGES.txt | 2 ++ .../apache/hadoop/fs/TrashPolicyDefault.java | 26 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 1cb8514d91f..04a4e2b049f 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -550,6 +550,8 @@ Release 0.23.3 - UNRELEASED HADOOP-8535. Cut hadoop build times in half (Job Eagles via bobby) + HADOOP-8110. Fix trash checkpoint collisions (Jason Lowe via daryn) + OPTIMIZATIONS BUG FIXES diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/TrashPolicyDefault.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/TrashPolicyDefault.java index 6bb4454db67..6993fd80f63 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/TrashPolicyDefault.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/TrashPolicyDefault.java @@ -35,6 +35,7 @@ import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configured; +import org.apache.hadoop.fs.Options.Rename; import org.apache.hadoop.fs.permission.FsAction; import org.apache.hadoop.fs.permission.FsPermission; @@ -148,21 +149,32 @@ public boolean moveToTrash(Path path) throws IOException { new IOException("Failed to move to trash: "+path).initCause(cause); } + @SuppressWarnings("deprecation") @Override public void createCheckpoint() throws IOException { if (!fs.exists(current)) // no trash, no checkpoint return; - Path checkpoint; + Path checkpointBase; synchronized (CHECKPOINT) { - checkpoint = new Path(trash, CHECKPOINT.format(new Date())); + checkpointBase = new Path(trash, CHECKPOINT.format(new Date())); + } + Path checkpoint = checkpointBase; + + int attempt = 0; + while (true) { + try { + fs.rename(current, checkpoint, Rename.NONE); + break; + } catch (FileAlreadyExistsException e) { + if (++attempt > 1000) { + throw new IOException("Failed to checkpoint trash: "+checkpoint); + } + checkpoint = checkpointBase.suffix("-" + attempt); + } } - if (fs.rename(current, checkpoint)) { - LOG.info("Created trash checkpoint: "+checkpoint.toUri().getPath()); - } else { - throw new IOException("Failed to checkpoint trash: "+checkpoint); - } + LOG.info("Created trash checkpoint: "+checkpoint.toUri().getPath()); } @Override