diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2019-06-21 11:00:05 +0200 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2019-07-03 21:34:29 +0200 |
commit | 850b9d7540025a974870bc75a2412ee91469a198 (patch) | |
tree | ee738c6ad19a24259aa4e7b273a2a5691f313f07 | |
parent | 1159f9dd7c80a53c2509cd75d997a6afed37f9a6 (diff) | |
download | jgit-850b9d7540025a974870bc75a2412ee91469a198.tar.gz jgit-850b9d7540025a974870bc75a2412ee91469a198.zip |
Timeout measuring file timestamp resolution after 2 seconds
It was reported that measuring file timestamp resolution may hang
indefinitely on nfs. Hence timeout this measurement at the known worst
filesystem timestamp resolution (FAT) of 2 seconds.
Bug: 548188
Change-Id: I17004b0aa49d5b0e76360a008af3adb911b289c0
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
3 files changed, 17 insertions, 2 deletions
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties index b7805b19e6..0a2f7029ed 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -680,6 +680,7 @@ theFactoryMustNotBeNull=The factory must not be null threadInterruptedWhileRunning="Current thread interrupted while running {0}" timeIsUncertain=Time is uncertain timerAlreadyTerminated=Timer already terminated +timeoutMeasureFsTimestampResolution=measuring filesystem timestamp resolution for ''{0}'' timed out, fall back to resolution of 2 seconds tooManyCommands=Too many commands tooManyFilters=Too many "filter" lines in request tooManyIncludeRecursions=Too many recursions; circular includes in config file(s)? diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java index da0ba4a775..bcd6d5ce27 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -737,6 +737,7 @@ public class JGitText extends TranslationBundle { /***/ public String tagAlreadyExists; /***/ public String tagNameInvalid; /***/ public String tagOnRepoWithoutHEADCurrentlyNotSupported; + /***/ public String timeoutMeasureFsTimestampResolution; /***/ public String transactionAborted; /***/ public String theFactoryMustNotBeNull; /***/ public String threadInterruptedWhileRunning; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java index e559d2167c..e7db6cee7a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -208,7 +208,7 @@ public abstract class FS { FileStore s = Files.getFileStore(dir); FileStoreAttributeCache c = attributeCache.get(s); if (c == null) { - c = new FileStoreAttributeCache(dir); + c = new FileStoreAttributeCache(s, dir); attributeCache.put(s, c); if (LOG.isDebugEnabled()) { LOG.debug(c.toString()); @@ -228,16 +228,24 @@ public abstract class FS { return fsTimestampResolution; } - private FileStoreAttributeCache(Path dir) + private FileStoreAttributeCache(FileStore s, Path dir) throws IOException, InterruptedException { Path probe = dir.resolve(".probe-" + UUID.randomUUID()); //$NON-NLS-1$ Files.createFile(probe); try { + long start = System.nanoTime(); FileTime startTime = Files.getLastModifiedTime(probe); FileTime actTime = startTime; long sleepTime = 512; while (actTime.compareTo(startTime) <= 0) { TimeUnit.NANOSECONDS.sleep(sleepTime); + if (timeout(start)) { + LOG.warn(MessageFormat.format(JGitText + .get().timeoutMeasureFsTimestampResolution, + s.toString())); + fsTimestampResolution = FALLBACK_TIMESTAMP_RESOLUTION; + return; + } FileUtils.touch(probe); actTime = Files.getLastModifiedTime(probe); // limit sleep time to max. 100ms @@ -254,6 +262,11 @@ public abstract class FS { } } + private static boolean timeout(long start) { + return System.nanoTime() - start >= FALLBACK_TIMESTAMP_RESOLUTION + .toNanos(); + } + @SuppressWarnings("nls") @Override public String toString() { |