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>
This commit is contained in:
Matthias Sohn 2019-06-21 11:00:05 +02:00
parent 1159f9dd7c
commit 850b9d7540
3 changed files with 17 additions and 2 deletions

View File

@ -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)?

View File

@ -737,6 +737,7 @@ public static JGitText get() {
/***/ public String tagAlreadyExists;
/***/ public String tagNameInvalid;
/***/ public String tagOnRepoWithoutHEADCurrentlyNotSupported;
/***/ public String timeoutMeasureFsTimestampResolution;
/***/ public String transactionAborted;
/***/ public String theFactoryMustNotBeNull;
/***/ public String threadInterruptedWhileRunning;

View File

@ -208,7 +208,7 @@ static Duration getFsTimestampResolution(Path file) {
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 @@ Duration getFsTimestampResolution() {
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 @@ private FileStoreAttributeCache(Path dir)
}
}
private static boolean timeout(long start) {
return System.nanoTime() - start >= FALLBACK_TIMESTAMP_RESOLUTION
.toNanos();
}
@SuppressWarnings("nls")
@Override
public String toString() {