]> source.dussan.org Git - jgit.git/commitdiff
Detect stale-file-handle error in causal chain 89/89589/5
authorHongkai Liu <hongkai.liu@ericsson.com>
Tue, 24 Jan 2017 19:08:25 +0000 (14:08 -0500)
committerHongkai Liu <hongkai.liu@ericsson.com>
Tue, 31 Jan 2017 02:36:59 +0000 (22:36 -0400)
Cover the case where the exception is wrapped up as a
cause, e.g., PackIndex#open(File).

Change-Id: I0df5b1e9c2ff886bdd84dee3658b6a50866699d1
Signed-off-by: Hongkai Liu <hongkai.liu@ericsson.com>
org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java

index 73d8038b9280bf7d7003a669ee42c71049662681..109d0e6ee3fdfbe44014fe78ced0ce0a11ce21b4 100644 (file)
@@ -50,10 +50,14 @@ import static org.junit.Assert.fail;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
+import java.rmi.RemoteException;
 import java.util.regex.Matcher;
 
+import javax.management.remote.JMXProviderException;
+
 import org.eclipse.jgit.junit.JGitTestUtil;
 import org.junit.After;
 import org.junit.Assume;
@@ -61,6 +65,17 @@ import org.junit.Before;
 import org.junit.Test;
 
 public class FileUtilsTest {
+       private static final String MSG = "Stale file handle";
+
+       private static final String SOME_ERROR_MSG = "some error message";
+
+       private static final IOException IO_EXCEPTION = new UnsupportedEncodingException(
+                       MSG);
+
+       private static final IOException IO_EXCEPTION_WITH_CAUSE = new RemoteException(
+                       SOME_ERROR_MSG,
+                       new JMXProviderException(SOME_ERROR_MSG, IO_EXCEPTION));
+
        private File trash;
 
        @Before
@@ -541,4 +556,29 @@ public class FileUtilsTest {
                return path.replaceAll("/|\\\\",
                                Matcher.quoteReplacement(File.separator));
        }
+
+       @Test
+       public void testIsStaleFileHandleWithDirectCause() throws Exception {
+               assertTrue(FileUtils.isStaleFileHandle(IO_EXCEPTION));
+       }
+
+       @Test
+       public void testIsStaleFileHandleWithIndirectCause() throws Exception {
+               assertFalse(
+                               FileUtils.isStaleFileHandle(IO_EXCEPTION_WITH_CAUSE));
+       }
+
+       @Test
+       public void testIsStaleFileHandleInCausalChainWithDirectCause()
+                       throws Exception {
+               assertTrue(
+                               FileUtils.isStaleFileHandleInCausalChain(IO_EXCEPTION));
+       }
+
+       @Test
+       public void testIsStaleFileHandleInCausalChainWithIndirectCause()
+                       throws Exception {
+               assertTrue(FileUtils
+                               .isStaleFileHandleInCausalChain(IO_EXCEPTION_WITH_CAUSE));
+       }
 }
index eec7fb7c3ab80530b4a5b7ca5eb3c645746bf5a3..b73152222be3e7478c49c5b0a02985eac7a34491 100644 (file)
@@ -577,7 +577,7 @@ public class ObjectDirectory extends FileObjectDatabase {
                                warnTmpl = JGitText.get().packWasDeleted;
                        }
                        removePack(p);
-               } else if (FileUtils.isStaleFileHandle(e)) {
+               } else if (FileUtils.isStaleFileHandleInCausalChain(e)) {
                        warnTmpl = JGitText.get().packHandleIsStale;
                        removePack(p);
                }
index e3d0d6162ccb8fa24f1b29d2d3a6cccf3bd4f054..023c08c77fe485baa9e3d8438c5854b52dc81fd8 100644 (file)
@@ -798,7 +798,8 @@ public class RefDirectory extends RefDatabase {
                                return new PackedRefList(parsePackedRefs(br), snapshot,
                                                ObjectId.fromRaw(digest.digest()));
                        } catch (IOException e) {
-                               if (FileUtils.isStaleFileHandle(e) && retries < maxStaleRetries) {
+                               if (FileUtils.isStaleFileHandleInCausalChain(e)
+                                               && retries < maxStaleRetries) {
                                        if (LOG.isDebugEnabled()) {
                                                LOG.debug(MessageFormat.format(
                                                                JGitText.get().packedRefsHandleIsStale,
index c04dfa96106d7401c82ee01d37a9474384746b4e..1f1d15b324a904752ee226cf6e3ced1b180de033 100644 (file)
@@ -547,6 +547,26 @@ public class FileUtils {
                                                .matches("stale .*file .*handle"); //$NON-NLS-1$
        }
 
+       /**
+        * Determine if a throwable or a cause in its causal chain is a Stale NFS
+        * File Handle
+        *
+        * @param throwable
+        * @return a boolean true if the throwable or a cause in its causal chain is
+        *         a Stale NFS File Handle
+        * @since 4.7
+        */
+       public static boolean isStaleFileHandleInCausalChain(Throwable throwable) {
+               while (throwable != null) {
+                       if (throwable instanceof IOException
+                                       && isStaleFileHandle((IOException) throwable)) {
+                               return true;
+                       }
+                       throwable = throwable.getCause();
+               }
+               return false;
+       }
+
        /**
         * @param file
         * @return {@code true} if the passed file is a symbolic link