Skip to content

Commit 8343791

Browse files
SendaoYanpull[bot]
SendaoYan
authored andcommitted
8338884: java/nio/file/attribute/BasicFileAttributeView/CreationTime.java#tmp fails on alinux3
Reviewed-by: sgehwolf, bpb
1 parent a86db3c commit 8343791

File tree

4 files changed

+200
-18
lines changed

4 files changed

+200
-18
lines changed

make/test/JtregNativeJdk.gmk

+2
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ ifeq ($(call isTargetOs, linux), true)
115115
# stripping during the test libraries' build.
116116
BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libFib := -g
117117
BUILD_JDK_JTREG_LIBRARIES_STRIP_SYMBOLS_libFib := false
118+
# nio tests' libCreationTimeHelper native needs -ldl linker flag
119+
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libCreationTimeHelper := -ldl
118120
endif
119121

120122
ifeq ($(ASAN_ENABLED), true)

test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTime.java

+20-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2024 Alibaba Group Holding Limited. All Rights Reserved.
34
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
45
*
56
* This code is free software; you can redistribute it and/or modify it
@@ -25,18 +26,18 @@
2526
* @bug 8011536 8151430 8316304 8334339
2627
* @summary Basic test for creationTime attribute on platforms/file systems
2728
* that support it, tests using /tmp directory.
28-
* @library ../.. /test/lib
29-
* @build jdk.test.lib.Platform
30-
* @run main CreationTime
29+
* @library ../.. /test/lib /java/foreign
30+
* @build jdk.test.lib.Platform NativeTestHelper
31+
* @run main/othervm/native --enable-native-access=ALL-UNNAMED CreationTime
3132
*/
3233

3334
/* @test id=cwd
3435
* @summary Basic test for creationTime attribute on platforms/file systems
3536
* that support it, tests using the test scratch directory, the test
3637
* scratch directory maybe at diff disk partition to /tmp on linux.
37-
* @library ../.. /test/lib
38-
* @build jdk.test.lib.Platform
39-
* @run main CreationTime .
38+
* @library ../.. /test/lib /java/foreign
39+
* @build jdk.test.lib.Platform NativeTestHelper
40+
* @run main/othervm/native --enable-native-access=ALL-UNNAMED CreationTime .
4041
*/
4142

4243
import java.lang.foreign.Linker;
@@ -51,8 +52,6 @@
5152

5253
public class CreationTime {
5354

54-
private static final java.io.PrintStream err = System.err;
55-
5655
/**
5756
* Reads the creationTime attribute
5857
*/
@@ -78,14 +77,9 @@ static void test(Path top) throws IOException {
7877
FileTime creationTime = creationTime(file);
7978
Instant now = Instant.now();
8079
if (Math.abs(creationTime.toMillis()-now.toEpochMilli()) > 10000L) {
81-
System.out.println("creationTime.toMillis() == " + creationTime.toMillis());
82-
// If the file system doesn't support birth time, then skip this test
83-
if (creationTime.toMillis() == 0) {
84-
throw new SkippedException("birth time not support for: " + file);
85-
} else {
86-
err.println("File creation time reported as: " + creationTime);
87-
throw new RuntimeException("Expected to be close to: " + now);
88-
}
80+
System.err.println("creationTime.toMillis() == " + creationTime.toMillis());
81+
System.err.println("File creation time reported as: " + creationTime);
82+
throw new RuntimeException("Expected to be close to: " + now);
8983
}
9084

9185
/**
@@ -107,7 +101,12 @@ static void test(Path top) throws IOException {
107101
}
108102
} else if (Platform.isLinux()) {
109103
// Creation time read depends on statx system call support
110-
supportsCreationTimeRead = Linker.nativeLinker().defaultLookup().find("statx").isPresent();
104+
try {
105+
supportsCreationTimeRead = CreationTimeHelper.
106+
linuxIsCreationTimeSupported(file.toAbsolutePath().toString());
107+
} catch (Throwable e) {
108+
supportsCreationTimeRead = false;
109+
}
111110
// Creation time updates are not supported on Linux
112111
supportsCreationTimeWrite = false;
113112
}
@@ -122,8 +121,11 @@ static void test(Path top) throws IOException {
122121
Instant plusHour = Instant.now().plusSeconds(60L * 60L);
123122
Files.setLastModifiedTime(file, FileTime.from(plusHour));
124123
FileTime current = creationTime(file);
125-
if (!current.equals(creationTime))
124+
if (!current.equals(creationTime)) {
125+
System.err.println("current = " + current);
126+
System.err.println("creationTime = " + creationTime);
126127
throw new RuntimeException("Creation time should not have changed");
128+
}
127129
}
128130

129131
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (c) 2024 Alibaba Group Holding Limited. All Rights Reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
import java.lang.foreign.Arena;
25+
import java.lang.foreign.FunctionDescriptor;
26+
import java.lang.foreign.Linker;
27+
import java.lang.foreign.MemorySegment;
28+
import java.lang.foreign.SymbolLookup;
29+
import java.lang.foreign.ValueLayout;
30+
import java.lang.invoke.MethodHandle;
31+
32+
public class CreationTimeHelper extends NativeTestHelper {
33+
34+
static {
35+
System.loadLibrary("CreationTimeHelper");
36+
}
37+
38+
final static Linker abi = Linker.nativeLinker();
39+
static final SymbolLookup lookup = SymbolLookup.loaderLookup();
40+
final static MethodHandle methodHandle = abi.
41+
downcallHandle(lookup.findOrThrow("linuxIsCreationTimeSupported"),
42+
FunctionDescriptor.of(C_BOOL, C_POINTER));
43+
44+
// Helper so as to determine birth time support or not on Linux.
45+
// Support is determined in a two-step process:
46+
// 1. Determine if `statx` system call is available. If available proceed,
47+
// otherwise return false.
48+
// 2. Perform an actual `statx` call on the given file and check for birth
49+
// time support in the mask returned from the call. This is needed,
50+
// since some file systems, like nfs/tmpfs etc., don't support birth
51+
// time even though the `statx` system call is available.
52+
static boolean linuxIsCreationTimeSupported(String file) throws Throwable {
53+
if (!abi.defaultLookup().find("statx").isPresent()) {
54+
return false;
55+
}
56+
try (var arena = Arena.ofConfined()) {
57+
MemorySegment s = arena.allocateFrom(file);
58+
return (boolean)methodHandle.invokeExact(s);
59+
}
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* Copyright (c) 2024 Alibaba Group Holding Limited. All Rights Reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
#include "export.h"
24+
#include <stdbool.h>
25+
#if defined(__linux__)
26+
#include <linux/fcntl.h>
27+
#include <stdio.h>
28+
#include <string.h>
29+
#include <sys/stat.h>
30+
#include <bits/types.h>
31+
#include <dlfcn.h>
32+
#ifndef STATX_BASIC_STATS
33+
#define STATX_BASIC_STATS 0x000007ffU
34+
#endif
35+
#ifndef STATX_BTIME
36+
#define STATX_BTIME 0x00000800U
37+
#endif
38+
#ifndef RTLD_DEFAULT
39+
#define RTLD_DEFAULT RTLD_LOCAL
40+
#endif
41+
42+
/*
43+
* Timestamp structure for the timestamps in struct statx.
44+
*/
45+
struct my_statx_timestamp {
46+
__int64_t tv_sec;
47+
__uint32_t tv_nsec;
48+
__int32_t __reserved;
49+
};
50+
51+
/*
52+
* struct statx used by statx system call on >= glibc 2.28
53+
* systems
54+
*/
55+
struct my_statx
56+
{
57+
__uint32_t stx_mask;
58+
__uint32_t stx_blksize;
59+
__uint64_t stx_attributes;
60+
__uint32_t stx_nlink;
61+
__uint32_t stx_uid;
62+
__uint32_t stx_gid;
63+
__uint16_t stx_mode;
64+
__uint16_t __statx_pad1[1];
65+
__uint64_t stx_ino;
66+
__uint64_t stx_size;
67+
__uint64_t stx_blocks;
68+
__uint64_t stx_attributes_mask;
69+
struct my_statx_timestamp stx_atime;
70+
struct my_statx_timestamp stx_btime;
71+
struct my_statx_timestamp stx_ctime;
72+
struct my_statx_timestamp stx_mtime;
73+
__uint32_t stx_rdev_major;
74+
__uint32_t stx_rdev_minor;
75+
__uint32_t stx_dev_major;
76+
__uint32_t stx_dev_minor;
77+
__uint64_t __statx_pad2[14];
78+
};
79+
80+
typedef int statx_func(int dirfd, const char *restrict pathname, int flags,
81+
unsigned int mask, struct my_statx *restrict statxbuf);
82+
83+
static statx_func* my_statx_func = NULL;
84+
#endif //#defined(__linux__)
85+
86+
// static boolean linuxIsCreationTimeSupported(char* file)
87+
EXPORT bool linuxIsCreationTimeSupported(char* file) {
88+
#if defined(__linux__)
89+
struct my_statx stx = {0};
90+
int ret, atflag = AT_SYMLINK_NOFOLLOW;
91+
unsigned int mask = STATX_BASIC_STATS | STATX_BTIME;
92+
93+
my_statx_func = (statx_func*) dlsym(RTLD_DEFAULT, "statx");
94+
if (my_statx_func == NULL) {
95+
return false;
96+
}
97+
98+
if (file == NULL) {
99+
printf("input file error!\n");
100+
return false;
101+
}
102+
103+
ret = my_statx_func(AT_FDCWD, file, atflag, mask, &stx);
104+
if (ret != 0) {
105+
return false;
106+
}
107+
// On some systems where statx is available but birth time might still not
108+
// be supported as it's file system specific. The only reliable way to
109+
// check for supported or not is looking at the filled in STATX_BTIME bit
110+
// in the returned statx buffer mask.
111+
if ((stx.stx_mask & STATX_BTIME) != 0)
112+
return true;
113+
return false;
114+
#else
115+
return false;
116+
#endif
117+
}

0 commit comments

Comments
 (0)