[v2] Y2038: provide kernel support indication
Commit Message
Introduce __ASSUME_KERNEL_Y2038_SUPPORT which means that
the underlying kernel *always* implements 64-bit-time Y2038-proof
syscalls.
If __ASSUME_KERNEL_Y2038_SUPPORT is not defined, glibc must
check dynamically whether the underlying kernel provides these
syscalls or not, and must fallback to 32-bit-time syscalls if
not.
Introduce function __y2038_get_kernel_support(), which returns
true if the underlying kernel supports 64-bit-time syscalls.
Also introduce function __y2038_set_kernel_support(), which
allows an implementation to notify glibc of the absence of
64-bit-time syscalls (ENOSYS) so that they are not needlessly
tried again.
* misc/Makefile: Add module y2038-support.
* misc/Versions: (__y2038_get_kernel_support): Add to GLIBC_PRIVATE.
* misc/Versions: (__y2038_set_kernel_support): Likewise.
* misc/y2038-support.c: New file.
* misc/y2038-support.h: Likewise.
* sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_KERNEL_Y2038_SUPPORT): Add.
* sysdeps/unix/sysv/linux/y2038-support.c: New file.
* sysdeps/unix/sysv/linux/y2038-support.h: New file.
---
misc/Makefile | 2 +-
misc/Versions | 4 ++
misc/y2038-support.c | 40 ++++++++++++++++++++
misc/y2038-support.h | 33 ++++++++++++++++
sysdeps/unix/sysv/linux/kernel-features.h | 14 +++++++
sysdeps/unix/sysv/linux/y2038-support.c | 46 +++++++++++++++++++++++
sysdeps/unix/sysv/linux/y2038-support.h | 34 +++++++++++++++++
7 files changed, 172 insertions(+), 1 deletion(-)
create mode 100644 misc/y2038-support.c
create mode 100644 misc/y2038-support.h
create mode 100644 sysdeps/unix/sysv/linux/y2038-support.c
create mode 100644 sysdeps/unix/sysv/linux/y2038-support.h
Comments
On Wed, 17 Oct 2018 13:19:11 +0200, "Albert ARIBAUD (3ADEV)"
<albert.aribaud@3adev.fr> wrote :
Note that
1. this patch is basically independent from the previously posted Y2038
patches, and
2. this patch was not tested using make check, as it only adds a
feature and accompanying functions, and does not modify any existing
functionality.
Cordialement,
Albert ARIBAUD
3ADEV
On Wed, 17 Oct 2018, Albert ARIBAUD (3ADEV) wrote:
> diff --git a/misc/Versions b/misc/Versions
> index 900e4ffb79..48285d8c42 100644
> --- a/misc/Versions
> +++ b/misc/Versions
> @@ -158,6 +158,8 @@ libc {
> GLIBC_2.26 {
> preadv2; preadv64v2; pwritev2; pwritev64v2;
> }
> + GLIBC_2.29 {
> + }
Why? I don't see any SHLIB_COMPAT or similar conditionals that might
require such an empty symbol version.
> +/* Support for Y2038-proof times.
> +
> + If defined, the underlying kernel always provides a set of syscalls
> + (__NR_* names and numbers) which can handle times beyond Y2038.
> +
> + If undefined, whether the underlying kernel provides this set or not
> + must be checked dynamically.
> +
> + Definition is commented out until Y2038 syscalls are merged in the
> + kernel.
I am unable to tell from this comment what the correct definition is for
64-bit systems where time_t in the default syscalls has always been
64-bit. That information needs to be completely obvious from the comment;
it needs to be completely explicit whether the macro relates to new
syscalls whose names explicitly refer to 64-bit times, or whether it
relates to syscalls supporting 64-bit times whose names might not mention
64-bit when on 64-bit platforms.
If the latter, the macro should of course be defined on 64-bit systems.
If the former, however, while the macro should then not be defined on
64-bit systems, the contents of y2038-support.c (both versions) must also
be conditioned out for __TIMESIZE == 64; there should be no additional
code added to libc binaries whatever in support of this feature on systems
where time_t is already 64-bit. (The declarations in y2038-support.h
should probably also be disabled in that case, to result in compile
failures if anything tries to call those functions with __TIMESIZE == 64.)
> +/* By default the underlying Linux kernel is assumed not to support Y2038.
> + * Any Linux architecture may (test and) claim Y2038 kernel support by
> + * setting __y2038_linux_support.
We don't use leading '*' on each comment line.
> +bool
> +__linux_y2038_get_kernel_support (void)
> +{
> + return __y2038_linux_support;
> +}
> +strong_alias (__linux_y2038_get_kernel_support, __y2038_get_kernel_support)
> +
> +void
> +__linux_y2038_set_kernel_support (bool support)
> +{
> + __y2038_linux_support = support;
Are you sure about using direct read / assignment like this rather than
relaxed atomics, which seem more logically correct for such cases (and
hopefully will generate the same code) where multiple threads might be
using the variable at once?
> +strong_alias (__linux_y2038_set_kernel_support, __y2038_set_kernel_support)
Why? The functions should never be accessed under the __linux_* names;
I'd expect them to be defined directly with the __y2038_* names, in both
files, rather than complicating things with __default_* / __linux_* names
and aliases. (You need to use libc_hidden_proto / libc_hidden_def,
however, since you have GLIBC_PRIVATE exports, so that accesses from
within libc.so use a hidden symbol name rather than going via the PLT.)
> +/* Indicates Y2038 support.
> + * Can be read directly from within libc linux-related files.
> + * Can be written non-zero to indicate support or lack thereof.
> + * Other libraries (e.g. librt) cannot access this variable and must
> + * call __y2038_get_kernel_support() and __y2038_set_kernel_support(). */
> +extern bool __y2038_linux_support;
Same point about comment formatting. If you have accessor functions, I
don't think you should be accessing this variable directly other than
through inline versions of those accessor functions. So either make this
variable static and remove that declaration, or add "#if IS_IN (libc)"
inline definitions of the accessors (and make that declaration, which
should also use attribute_hidden, conditional on IS_IN (libc) as well).
On Wed, 17 Oct 2018, Albert ARIBAUD wrote:
> 2. this patch was not tested using make check, as it only adds a
> feature and accompanying functions, and does not modify any existing
> functionality.
It adds new C code built into libc. That always needs testing with "make
check", to verify that it doesn't introduce any ABI test failures, for
example.
@@ -71,7 +71,7 @@ routines := brk sbrk sstk ioctl \
fgetxattr flistxattr fremovexattr fsetxattr getxattr \
listxattr lgetxattr llistxattr lremovexattr lsetxattr \
removexattr setxattr getauxval ifunc-impl-list makedev \
- allocate_once
+ allocate_once y2038-support
generated += tst-error1.mtrace tst-error1-mem.out \
tst-allocate_once.mtrace tst-allocate_once-mem.out
@@ -158,6 +158,8 @@ libc {
GLIBC_2.26 {
preadv2; preadv64v2; pwritev2; pwritev64v2;
}
+ GLIBC_2.29 {
+ }
GLIBC_PRIVATE {
__madvise;
__mktemp;
@@ -166,5 +168,7 @@ libc {
__mmap; __munmap; __mprotect;
__sched_get_priority_min; __sched_get_priority_max;
__libc_allocate_once_slow;
+ __y2038_get_kernel_support;
+ __y2038_set_kernel_support;
}
}
new file mode 100644
@@ -0,0 +1,40 @@
+/* y2038 general kernel support indication.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdbool.h>
+
+#ifndef __ASSUME_KERNEL_Y2038_SUPPORT
+
+/* By default glibc assumes the underlying kernel does not support Y2038. */
+bool
+__default_y2038_get_kernel_support (void)
+{
+ return false;
+}
+weak_alias (__default_y2038_get_kernel_support, __y2038_get_kernel_support)
+
+/* By default glibc just ignores Y2038 support indication setting. */
+void
+__default_y2038_set_kernel_support (bool support __attribute__ ((unused)))
+{
+ /* Do nothing. */
+}
+weak_alias (__default_y2038_set_kernel_support, __y2038_set_kernel_support)
+
+#endif
new file mode 100644
@@ -0,0 +1,33 @@
+/* y2038 general kernel support indication.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdbool.h>
+
+/* If we do not assume that the kernel provides 64-bit-time syscalls,
+ * then we need a dynamic way to remember whether it does or not. */
+
+#ifndef __ASSUME_KERNEL_Y2038_SUPPORT
+
+/* Dynamically check whether actual kernel supports Y2038 or not. */
+extern bool __y2038_get_kernel_support (void);
+
+/* Dynamically set whether actual kernel supports Y2038 or not. */
+extern void __y2038_set_kernel_support (bool support);
+
+#endif
@@ -154,3 +154,17 @@
*/
#define __ASSUME_CLONE_DEFAULT 1
+
+/* Support for Y2038-proof times.
+
+ If defined, the underlying kernel always provides a set of syscalls
+ (__NR_* names and numbers) which can handle times beyond Y2038.
+
+ If undefined, whether the underlying kernel provides this set or not
+ must be checked dynamically.
+
+ Definition is commented out until Y2038 syscalls are merged in the
+ kernel.
+ */
+
+/* #define __ASSUME_KERNEL_Y2038_SUPPORT 1 */
new file mode 100644
@@ -0,0 +1,46 @@
+/* y2038 Linux kernel support indication.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef __ASSUME_KERNEL_Y2038_SUPPORT
+
+#include <stdbool.h>
+
+/* By default the underlying Linux kernel is assumed not to support Y2038.
+ * Any Linux architecture may (test and) claim Y2038 kernel support by
+ * setting __y2038_linux_support.
+ */
+bool __y2038_linux_support = false;
+
+/* For Linux, Y2038 kernel support is determined by __y2038_linux_support. */
+
+bool
+__linux_y2038_get_kernel_support (void)
+{
+ return __y2038_linux_support;
+}
+strong_alias (__linux_y2038_get_kernel_support, __y2038_get_kernel_support)
+
+void
+__linux_y2038_set_kernel_support (bool support)
+{
+ __y2038_linux_support = support;
+}
+strong_alias (__linux_y2038_set_kernel_support, __y2038_set_kernel_support)
+
+#endif
new file mode 100644
@@ -0,0 +1,34 @@
+/* y2038 Linux kernel support indication.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef __ASSUME_KERNEL_Y2038_SUPPORT
+
+#include <stdbool.h>
+
+/* Indicates Y2038 support.
+ * Can be read directly from within libc linux-related files.
+ * Can be written non-zero to indicate support or lack thereof.
+ * Other libraries (e.g. librt) cannot access this variable and must
+ * call __y2038_get_kernel_support() and __y2038_set_kernel_support(). */
+extern bool __y2038_linux_support;
+
+#endif
+
+/* As a fallback, provide generic Y2038 support indication. */
+#include <misc/y2038-support.h>