From 3c2101ae4a65af4b68a08651c27966490e8fbef0 Mon Sep 17 00:00:00 2001 From: Daryn Sharp Date: Tue, 3 Jul 2012 19:59:56 +0000 Subject: [PATCH] HADOOP-8110. Fix trash checkpoint collisions (Jason Lowe via daryn) git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1356897 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 ecaaa3b956..5fe4f0156d 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -167,6 +167,8 @@ Trunk (unreleased changes) HADOOP-8548. test-patch.sh shows an incorrect link in Jekins builds (Kihwal Lee via bobby) + HADOOP-8110. Fix trash checkpoint collisions (Jason Lowe via daryn) + OPTIMIZATIONS HADOOP-7761. Improve the performance of raw comparisons. (todd) 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 6bb4454db6..6993fd80f6 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