|
16 | 16 | import java.nio.file.Path;
|
17 | 17 | import java.nio.file.Paths;
|
18 | 18 | import java.nio.file.attribute.BasicFileAttributes;
|
| 19 | +import java.nio.file.attribute.PosixFilePermission; |
19 | 20 | import java.nio.file.attribute.PosixFilePermissions;
|
20 | 21 | import java.time.Instant;
|
21 | 22 | import java.time.temporal.ChronoUnit;
|
22 | 23 | import java.util.Set;
|
23 | 24 | import java.util.concurrent.CountDownLatch;
|
24 | 25 | import java.util.concurrent.TimeUnit;
|
| 26 | +import java.util.concurrent.atomic.AtomicReference; |
25 | 27 | import java.util.regex.Pattern;
|
26 | 28 | import java.util.stream.Stream;
|
27 | 29 | import org.slf4j.Logger;
|
@@ -219,6 +221,7 @@ boolean await(long timeout, TimeUnit unit) throws Throwable {
|
219 | 221 | }
|
220 | 222 | }
|
221 | 223 |
|
| 224 | + private final boolean isPosixFs; |
222 | 225 | private final Path baseTempDir;
|
223 | 226 | private final Path tempDir;
|
224 | 227 | private final long cutoffSeconds;
|
@@ -262,6 +265,9 @@ private TempLocationManager() {
|
262 | 265 | ConfigProvider configProvider, boolean runStartupCleanup, CleanupHook testHook) {
|
263 | 266 | cleanupTestHook = testHook;
|
264 | 267 |
|
| 268 | + Set<String> supportedViews = FileSystems.getDefault().supportedFileAttributeViews(); |
| 269 | + isPosixFs = supportedViews.contains("posix"); |
| 270 | + |
265 | 271 | // In order to avoid racy attempts to clean up files which are currently being processed in a
|
266 | 272 | // JVM which is being shut down (the JVMs far in the shutdown routine may not be reported by
|
267 | 273 | // 'jps' but still can be eg. processing JFR chunks) we will not clean up any files not older
|
@@ -317,6 +323,8 @@ private TempLocationManager() {
|
317 | 323 | },
|
318 | 324 | "Temp Location Manager Cleanup");
|
319 | 325 | Runtime.getRuntime().addShutdownHook(selfCleanup);
|
| 326 | + |
| 327 | + createTempDir(tempDir); |
320 | 328 | }
|
321 | 329 |
|
322 | 330 | // @VisibleForTesting
|
@@ -362,21 +370,7 @@ public Path getTempDir(Path subPath, boolean create) {
|
362 | 370 | Path rslt =
|
363 | 371 | subPath != null && !subPath.toString().isEmpty() ? tempDir.resolve(subPath) : tempDir;
|
364 | 372 | if (create && !Files.exists(rslt)) {
|
365 |
| - try { |
366 |
| - Set<String> supportedViews = FileSystems.getDefault().supportedFileAttributeViews(); |
367 |
| - if (supportedViews.contains("posix")) { |
368 |
| - Files.createDirectories( |
369 |
| - rslt, |
370 |
| - PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------"))); |
371 |
| - } else { |
372 |
| - // non-posix, eg. Windows - let's rely on the created folders being world-writable |
373 |
| - Files.createDirectories(rslt); |
374 |
| - } |
375 |
| - |
376 |
| - } catch (Exception e) { |
377 |
| - log.warn(SEND_TELEMETRY, "Failed to create temp directory: {}", tempDir, e); |
378 |
| - throw new IllegalStateException("Failed to create temp directory: " + tempDir, e); |
379 |
| - } |
| 373 | + createTempDir(rslt); |
380 | 374 | }
|
381 | 375 | return rslt;
|
382 | 376 | }
|
@@ -454,4 +448,78 @@ boolean waitForCleanup(long timeout, TimeUnit unit) {
|
454 | 448 | void createDirStructure() throws IOException {
|
455 | 449 | Files.createDirectories(baseTempDir);
|
456 | 450 | }
|
| 451 | + |
| 452 | + private void createTempDir(Path tempDir) { |
| 453 | + String msg = "Failed to create temp directory: " + tempDir; |
| 454 | + try { |
| 455 | + if (isPosixFs) { |
| 456 | + Files.createDirectories( |
| 457 | + tempDir, |
| 458 | + PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------"))); |
| 459 | + } else { |
| 460 | + Files.createDirectories(tempDir); |
| 461 | + } |
| 462 | + } catch (IOException e) { |
| 463 | + log.error("Failed to create temp directory {}", tempDir, e); |
| 464 | + // if on a posix fs, let's check the expected permissions |
| 465 | + // we will find the first offender not having the expected permissions and fail the check |
| 466 | + if (isPosixFs) { |
| 467 | + Path root = baseTempDir.resolve(tempDir.relativize(baseTempDir).getRoot()); |
| 468 | + try { |
| 469 | + AtomicReference<Path> failed = new AtomicReference<>(); |
| 470 | + Files.walkFileTree( |
| 471 | + root, |
| 472 | + new FileVisitor<Path>() { |
| 473 | + @Override |
| 474 | + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) |
| 475 | + throws IOException { |
| 476 | + Set<PosixFilePermission> perms = Files.getPosixFilePermissions(dir); |
| 477 | + if (!perms.contains(PosixFilePermission.OWNER_READ) |
| 478 | + || !perms.contains(PosixFilePermission.OWNER_WRITE) |
| 479 | + || !perms.contains(PosixFilePermission.OWNER_EXECUTE)) { |
| 480 | + failed.set(dir); |
| 481 | + return FileVisitResult.TERMINATE; |
| 482 | + } |
| 483 | + return FileVisitResult.CONTINUE; |
| 484 | + } |
| 485 | + |
| 486 | + @Override |
| 487 | + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) |
| 488 | + throws IOException { |
| 489 | + return FileVisitResult.SKIP_SIBLINGS; |
| 490 | + } |
| 491 | + |
| 492 | + @Override |
| 493 | + public FileVisitResult visitFileFailed(Path file, IOException exc) |
| 494 | + throws IOException { |
| 495 | + return FileVisitResult.TERMINATE; |
| 496 | + } |
| 497 | + |
| 498 | + @Override |
| 499 | + public FileVisitResult postVisitDirectory(Path dir, IOException exc) |
| 500 | + throws IOException { |
| 501 | + return FileVisitResult.CONTINUE; |
| 502 | + } |
| 503 | + }); |
| 504 | + Path failedDir = failed.get(); |
| 505 | + |
| 506 | + if (failedDir != null) { |
| 507 | + msg += |
| 508 | + " (offender: " |
| 509 | + + failedDir |
| 510 | + + ", permissions: " |
| 511 | + + PosixFilePermissions.toString(Files.getPosixFilePermissions(failedDir)) |
| 512 | + + ")"; |
| 513 | + log.warn(SEND_TELEMETRY, msg, e); |
| 514 | + } |
| 515 | + } catch (IOException ignored) { |
| 516 | + // should not happen, but let's ignore it anyway' |
| 517 | + } |
| 518 | + throw new IllegalStateException(msg, e); |
| 519 | + } else { |
| 520 | + log.warn(SEND_TELEMETRY, msg, e); |
| 521 | + throw new IllegalStateException(msg, e); |
| 522 | + } |
| 523 | + } |
| 524 | + } |
457 | 525 | }
|
0 commit comments