Linux: Remove <sys/sysctl.h> and the sysctl function

Message ID 87imjeee7s.fsf@mid.deneb.enyo.de
State Superseded
Headers
Series Linux: Remove <sys/sysctl.h> and the sysctl function |

Commit Message

Florian Weimer March 8, 2020, 9:20 p.m. UTC
  The sysctl compat function always fails with ENOSYS because even for
architectures which in theory support the system call, it is usually
disabled at kernel build time (following the kernel default).

Due to SHLIB_COMPAT, new ports will not add the sysctl function anymore
automatically.

The NEED_PRIVATE_SYSCTL flag is required because the powerpc64le port
is not a generic ABI port and it has a 2.17 ABI baseline, the same
as the aarch64 port, which is a port that uses the generic sysdeps
directory.  Therefore, using the ABI baseline to control the __sysctl
symbol availability is not possible.

x32 already lacks the sysctl function, so an empty sysctl.c file is
used to suppress it.  Otherwise, a new compat symbol would be added.

-----
 NEWS                                               |   4 +-
 include/sys/sysctl.h                               |   3 -
 manual/sysinfo.texi                                | 144 ---------------------
 scripts/check-installed-headers.sh                 |   5 -
 sysdeps/unix/sysv/linux/Makefile                   |   8 +-
 sysdeps/unix/sysv/linux/Versions                   |   2 +
 sysdeps/unix/sysv/linux/bits/sysctl.h              |   1 -
 sysdeps/unix/sysv/linux/generic/sysctl.c           |  24 +---
 sysdeps/unix/sysv/linux/sys/sysctl.h               |  76 -----------
 .../linux/{x86/bits/sysctl.h => sysctl-common.h}   |  26 +++-
 sysdeps/unix/sysv/linux/sysctl.c                   |  29 +----
 sysdeps/unix/sysv/linux/sysctl.mk                  |   3 -
 sysdeps/unix/sysv/linux/x86_64/x32/sysctl.c        |   2 +
 sysdeps/unix/sysv/linux/x86_64/x32/sysctl.mk       |   1 -
 14 files changed, 45 insertions(+), 283 deletions(-)
  

Comments

Adhemerval Zanella March 11, 2020, 5:16 p.m. UTC | #1
On 08/03/2020 18:20, Florian Weimer wrote:
> The sysctl compat function always fails with ENOSYS because even for
> architectures which in theory support the system call, it is usually
> disabled at kernel build time (following the kernel default).

I aleady summarized my take on sysctl deprecation/removal [1], but
Zack did not reply based on his take to not remove it [2].

And, besides the deprecation done in last release, I foresee that
the header removal will most likely break some projects. But it should
not block this change imho.

[1] https://sourceware.org/legacy-ml/libc-alpha/2018-05/msg00067.html
[2] https://sourceware.org/legacy-ml/libc-alpha/2018-04/msg00633.html

> 
> Due to SHLIB_COMPAT, new ports will not add the sysctl function anymore
> automatically.
> 
> The NEED_PRIVATE_SYSCTL flag is required because the powerpc64le port
> is not a generic ABI port and it has a 2.17 ABI baseline, the same
> as the aarch64 port, which is a port that uses the generic sysdeps
> directory.  Therefore, using the ABI baseline to control the __sysctl
> symbol availability is not possible.
> 
> x32 already lacks the sysctl function, so an empty sysctl.c file is
> used to suppress it.  Otherwise, a new compat symbol would be added.
> 
> -----
>  NEWS                                               |   4 +-
>  include/sys/sysctl.h                               |   3 -
>  manual/sysinfo.texi                                | 144 ---------------------
>  scripts/check-installed-headers.sh                 |   5 -
>  sysdeps/unix/sysv/linux/Makefile                   |   8 +-
>  sysdeps/unix/sysv/linux/Versions                   |   2 +
>  sysdeps/unix/sysv/linux/bits/sysctl.h              |   1 -
>  sysdeps/unix/sysv/linux/generic/sysctl.c           |  24 +---
>  sysdeps/unix/sysv/linux/sys/sysctl.h               |  76 -----------
>  .../linux/{x86/bits/sysctl.h => sysctl-common.h}   |  26 +++-
>  sysdeps/unix/sysv/linux/sysctl.c                   |  29 +----
>  sysdeps/unix/sysv/linux/sysctl.mk                  |   3 -
>  sysdeps/unix/sysv/linux/x86_64/x32/sysctl.c        |   2 +
>  sysdeps/unix/sysv/linux/x86_64/x32/sysctl.mk       |   1 -
>  14 files changed, 45 insertions(+), 283 deletions(-)
> 
> diff --git a/NEWS b/NEWS
> index 77631ca707..97be07be31 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -13,7 +13,9 @@ Major new features:
>  
>  Deprecated and removed features, and other changes affecting compatibility:
>  
> -  [Add deprecations, removals and changes affecting compatibility here]
> +* The deprecated <sys/sysctl.h> header and the sysctl function have been
> +  removed.  For compatibility with old binaries, the sysctl function
> +  continues to exist, but always fails with ENOSYS.
>  
>  Changes to build and runtime requirements:
>  

Ok.

> diff --git a/include/sys/sysctl.h b/include/sys/sysctl.h
> deleted file mode 100644
> index fa102aa226..0000000000
> --- a/include/sys/sysctl.h
> +++ /dev/null
> @@ -1,3 +0,0 @@
> -#ifndef _SYS_SYSCTL_H
> -#include_next <sys/sysctl.h>
> -#endif  /* _SYS_SYSCTL_H */

Ok.

> diff --git a/manual/sysinfo.texi b/manual/sysinfo.texi
> index 4beee0129b..4ca4555443 100644
> --- a/manual/sysinfo.texi
> +++ b/manual/sysinfo.texi
> @@ -14,7 +14,6 @@ can make changes.
>  * Platform Type::               Determining operating system and basic
>                                    machine type
>  * Filesystem Handling::         Controlling/querying mounts
> -* System Parameters::           Getting and setting various system parameters
>  @end menu
>  
>  To get information on parameters of the system that are built into the
> @@ -1107,146 +1106,3 @@ to zeroes.  It is more widely available than @code{umount2} but since it
>  lacks the possibility to forcefully unmount a filesystem is deprecated
>  when @code{umount2} is also available.
>  @end deftypefun
> -
> -
> -
> -@node System Parameters
> -@section System Parameters
> -
> -This section describes the @code{sysctl} function, which gets and sets
> -a variety of system parameters.
> -
> -The symbols used in this section are declared in the file @file{sys/sysctl.h}.
> -
> -@deftypefun int sysctl (int *@var{names}, int @var{nlen}, void *@var{oldval}, size_t *@var{oldlenp}, void *@var{newval}, size_t @var{newlen})
> -@standards{BSD, sys/sysctl.h}
> -@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
> -@c Direct syscall, Linux only.
> -
> -@code{sysctl} gets or sets a specified system parameter.  There are so
> -many of these parameters that it is not practical to list them all here,
> -but here are some examples:
> -
> -@itemize @bullet
> -@item network domain name
> -@item paging parameters
> -@item network Address Resolution Protocol timeout time
> -@item maximum number of files that may be open
> -@item root filesystem device
> -@item when kernel was built
> -@end itemize
> -
> -The set of available parameters depends on the kernel configuration and
> -can change while the system is running, particularly when you load and
> -unload loadable kernel modules.
> -
> -The system parameters with which @code{sysctl} is concerned are arranged
> -in a hierarchical structure like a hierarchical filesystem.  To identify
> -a particular parameter, you specify a path through the structure in a
> -way analogous to specifying the pathname of a file.  Each component of
> -the path is specified by an integer and each of these integers has a
> -macro defined for it by @file{sys/sysctl.h}.  @var{names} is the path, in
> -the form of an array of integers.  Each component of the path is one
> -element of the array, in order.  @var{nlen} is the number of components
> -in the path.
> -
> -For example, the first component of the path for all the paging
> -parameters is the value @code{CTL_VM}.  For the free page thresholds, the
> -second component of the path is @code{VM_FREEPG}.  So to get the free
> -page threshold values, make @var{names} an array containing the two
> -elements @code{CTL_VM} and @code{VM_FREEPG} and make @var{nlen} = 2.
> -
> -
> -The format of the value of a parameter depends on the parameter.
> -Sometimes it is an integer; sometimes it is an ASCII string; sometimes
> -it is an elaborate structure.  In the case of the free page thresholds
> -used in the example above, the parameter value is a structure containing
> -several integers.
> -
> -In any case, you identify a place to return the parameter's value with
> -@var{oldval} and specify the amount of storage available at that
> -location as *@var{oldlenp}.  *@var{oldlenp} does double duty because it
> -is also the output location that contains the actual length of the
> -returned value.
> -
> -If you don't want the parameter value returned, specify a null pointer
> -for @var{oldval}.
> -
> -To set the parameter, specify the address and length of the new value
> -as @var{newval} and @var{newlen}.  If you don't want to set the parameter,
> -specify a null pointer as @var{newval}.
> -
> -If you get and set a parameter in the same @code{sysctl} call, the value
> -returned is the value of the parameter before it was set.
> -
> -Each system parameter has a set of permissions similar to the
> -permissions for a file (including the permissions on directories in its
> -path) that determine whether you may get or set it.  For the purposes of
> -these permissions, every parameter is considered to be owned by the
> -superuser and Group 0 so processes with that effective uid or gid may
> -have more access to system parameters.  Unlike with files, the superuser
> -does not invariably have full permission to all system parameters, because
> -some of them are designed not to be changed ever.
> -
> -
> -@code{sysctl} returns a zero return value if it succeeds.  Otherwise, it
> -returns @code{-1} and sets @code{errno} appropriately.  Besides the
> -failures that apply to all system calls, the following are the
> -@code{errno} codes for all possible failures:
> -
> -@table @code
> -@item EPERM
> -The process is not permitted to access one of the components of the
> -path of the system parameter or is not permitted to access the system parameter
> -itself in the way (read or write) that it requested.
> -@c There is some indication in the Linux 2.2 code that the code is trying to
> -@c return EACCES here, but the EACCES value never actually makes it to the
> -@c user.
> -@item ENOTDIR
> -There is no system parameter corresponding to @var{name}.
> -@item EFAULT
> -@var{oldval} is not null, which means the process wanted to read the parameter,
> -but *@var{oldlenp} is zero, so there is no place to return it.
> -@item EINVAL
> -@itemize @bullet
> -@item
> -The process attempted to set a system parameter to a value that is not valid
> -for that parameter.
> -@item
> -The space provided for the return of the system parameter is not the right
> -size for that parameter.
> -@end itemize
> -@item ENOMEM
> -This value may be returned instead of the more correct @code{EINVAL} in some
> -cases where the space provided for the return of the system parameter is too
> -small.
> -
> -@end table
> -
> -@end deftypefun
> -
> -If you have a Linux kernel with the @code{proc} filesystem, you can get
> -and set most of the same parameters by reading and writing to files in
> -the @code{sys} directory of the @code{proc} filesystem.  In the @code{sys}
> -directory, the directory structure represents the hierarchical structure
> -of the parameters.  E.g. you can display the free page thresholds with
> -@smallexample
> -cat /proc/sys/vm/freepages
> -@end smallexample
> -@c In Linux, the sysctl() and /proc instances of the parameter are created
> -@c together.  The proc filesystem accesses the same data structure as
> -@c sysctl(), which has special fields in it for /proc.  But it is still
> -@c possible to create a sysctl-only parameter.
> -
> -Some more traditional and more widely available, though less general,
> -@glibcadj{} functions for getting and setting some of the same system
> -parameters are:
> -
> -@itemize @bullet
> -@item
> -@code{getdomainname}, @code{setdomainname}
> -@item
> -@code{gethostname}, @code{sethostname} (@xref{Host Identification}.)
> -@item
> -@code{uname} (@xref{Platform Type}.)
> -@end itemize

Ok.

> diff --git a/scripts/check-installed-headers.sh b/scripts/check-installed-headers.sh
> index f70340f098..aab56cf405 100644
> --- a/scripts/check-installed-headers.sh
> +++ b/scripts/check-installed-headers.sh
> @@ -74,11 +74,6 @@ for header in "$@"; do
>          (finclude/*)
>              continue;;
>  
> -	# sys/sysctl.h produces a deprecation warning and therefore
> -	# fails compilation with -Werror.
> -	(sys/sysctl.h)
> -	    continue;;
> -
>          # sys/vm86.h is "unsupported on x86-64" and errors out on that target.
>          (sys/vm86.h)
>              case "$is_x86_64" in

Ok.

> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index 60dc5cf9e5..089a4899d5 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -54,9 +54,7 @@ CFLAGS-malloc.c += -DMORECORE_CLEARS=2
>  endif
>  
>  ifeq ($(subdir),misc)
> -include $(firstword $(wildcard $(sysdirs:=/sysctl.mk)))
> -
> -sysdep_routines += adjtimex clone umount umount2 readahead \
> +sysdep_routines += adjtimex clone umount umount2 readahead sysctl \
>  		   setfsuid setfsgid epoll_pwait signalfd \
>  		   eventfd eventfd_read eventfd_write prlimit \
>  		   personality epoll_wait tee vmsplice splice \

Ok.

> @@ -71,7 +69,7 @@ CFLAGS-open_by_handle_at.c = -fexceptions -fasynchronous-unwind-tables
>  CFLAGS-sync_file_range.c = -fexceptions -fasynchronous-unwind-tables
>  CFLAGS-tst-writev.c += "-DARTIFICIAL_LIMIT=(0x80000000-sysconf(_SC_PAGESIZE))"
>  
> -sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
> +sysdep_headers += sys/mount.h sys/acct.h \
>  		  sys/klog.h \
>  		  sys/user.h sys/prctl.h \
>  		  sys/kd.h sys/soundcard.h sys/vt.h \
> @@ -81,7 +79,7 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
>  		  bits/a.out.h sys/inotify.h sys/signalfd.h sys/eventfd.h \
>  		  sys/timerfd.h sys/fanotify.h bits/eventfd.h bits/inotify.h \
>  		  bits/signalfd.h bits/timerfd.h bits/epoll.h \
> -		  bits/socket_type.h bits/syscall.h bits/sysctl.h \
> +		  bits/socket_type.h bits/syscall.h \
>  		  bits/mman-linux.h bits/mman-shared.h bits/ptrace-shared.h \
>  		  bits/siginfo-arch.h bits/siginfo-consts-arch.h \
>  		  bits/procfs.h bits/procfs-id.h bits/procfs-extra.h \

Ok.

> diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
> index d385085c61..9a58dda9f2 100644
> --- a/sysdeps/unix/sysv/linux/Versions
> +++ b/sysdeps/unix/sysv/linux/Versions
> @@ -177,6 +177,8 @@ libc {
>    GLIBC_2.30 {
>      getdents64; gettid; tgkill;
>    }
> +  GLIBC_2.32 {
> +  }
>    GLIBC_PRIVATE {
>      # functions used in other libraries
>      __syscall_rt_sigqueueinfo;

Ok.

> diff --git a/sysdeps/unix/sysv/linux/bits/sysctl.h b/sysdeps/unix/sysv/linux/bits/sysctl.h
> deleted file mode 100644
> index 81447b2f74..0000000000
> --- a/sysdeps/unix/sysv/linux/bits/sysctl.h
> +++ /dev/null
> @@ -1 +0,0 @@
> -/* Empty file.  */

Ok.

> diff --git a/sysdeps/unix/sysv/linux/generic/sysctl.c b/sysdeps/unix/sysv/linux/generic/sysctl.c
> index e7d5a3cf93..c2ca30268b 100644
> --- a/sysdeps/unix/sysv/linux/generic/sysctl.c
> +++ b/sysdeps/unix/sysv/linux/generic/sysctl.c
> @@ -1,6 +1,6 @@
> -/* Copyright (C) 2011-2020 Free Software Foundation, Inc.
> +/* sysctl function stub.  generic subdirectory version.
> +   Copyright (C) 1996-2020 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
> -   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
>  
>     The GNU C Library is free software; you can redistribute it and/or
>     modify it under the terms of the GNU Lesser General Public
> @@ -13,20 +13,10 @@
>     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
> +   License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#include <errno.h>
> -
> -#include <sysdep.h>
> -#include <sys/syscall.h>
> -
> -/* This deprecated syscall is no longer used (replaced with /proc/sys).  */
> -int
> -sysctl (int *name, int nlen, void *oldval, size_t *oldlenp,
> -        void *newval, size_t newlen)
> -{
> -  __set_errno (ENOSYS);
> -  return -1;
> -}
> -stub_warning (sysctl)
> +/* The sysctl definition from the generic subdirectory does not
> +   include the __sysctl compat symbol.  */
> +#define NEED_PRIVATE_SYSCTL 0
> +#include <sysdeps/unix/sysv/linux/sysctl-common.h>

Wouldn't be better to define the NEED_PRIVATE_SYSCTL per architecture
instead and remove this generic file?

(My idea is to remove the 'generic' folder in the long term, since its
name is misleading and ideally the linux default implementation should
use the generic kABI intended for new abis.)

> diff --git a/sysdeps/unix/sysv/linux/sys/sysctl.h b/sysdeps/unix/sysv/linux/sys/sysctl.h
> deleted file mode 100644
> index 1ead597244..0000000000
> --- a/sysdeps/unix/sysv/linux/sys/sysctl.h
> +++ /dev/null
> @@ -1,76 +0,0 @@
> -/* Copyright (C) 1996-2020 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
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#ifndef	_SYS_SYSCTL_H
> -#define	_SYS_SYSCTL_H	1
> -
> -#warning "The <sys/sysctl.h> header is deprecated and will be removed."
> -
> -#include <features.h>
> -#define __need_size_t
> -#include <stddef.h>
> -/* Prevent more kernel headers than necessary to be included.  */
> -#ifndef _LINUX_KERNEL_H
> -# define _LINUX_KERNEL_H	1
> -# define __undef_LINUX_KERNEL_H
> -#endif
> -#ifndef _LINUX_TYPES_H
> -# define _LINUX_TYPES_H		1
> -# define __undef_LINUX_TYPES_H
> -#endif
> -#ifndef _LINUX_LIST_H
> -# define _LINUX_LIST_H		1
> -# define __undef_LINUX_LIST_H
> -#endif
> -#ifndef __LINUX_COMPILER_H
> -# define __LINUX_COMPILER_H	1
> -# define __user
> -# define __undef__LINUX_COMPILER_H
> -#endif
> -
> -#include <linux/sysctl.h>
> -
> -#ifdef __undef_LINUX_KERNEL_H
> -# undef _LINUX_KERNEL_H
> -# undef __undef_LINUX_KERNEL_H
> -#endif
> -#ifdef __undef_LINUX_TYPES_H
> -# undef _LINUX_TYPES_H
> -# undef __undef_LINUX_TYPES_H
> -#endif
> -#ifdef __undef_LINUX_LIST_H
> -# undef _LINUX_LIST_H
> -# undef __undef_LINUX_LIST_H
> -#endif
> -#ifdef __undef__LINUX_COMPILER_H
> -# undef __LINUX_COMPILER_H
> -# undef __user
> -# undef __undef__LINUX_COMPILER_H
> -#endif
> -
> -#include <bits/sysctl.h>
> -
> -__BEGIN_DECLS
> -
> -/* Read or write system parameters.  */
> -extern int sysctl (int *__name, int __nlen, void *__oldval,
> -		   size_t *__oldlenp, void *__newval, size_t __newlen) __THROW
> -  __attribute_deprecated__;
> -
> -__END_DECLS
> -
> -#endif	/* _SYS_SYSCTL_H */

Ok.

> diff --git a/sysdeps/unix/sysv/linux/x86/bits/sysctl.h b/sysdeps/unix/sysv/linux/sysctl-common.h
> similarity index 50%
> rename from sysdeps/unix/sysv/linux/x86/bits/sysctl.h
> rename to sysdeps/unix/sysv/linux/sysctl-common.h
> index 873a2af109..84ace6ee67 100644
> --- a/sysdeps/unix/sysv/linux/x86/bits/sysctl.h
> +++ b/sysdeps/unix/sysv/linux/sysctl-common.h
> @@ -1,4 +1,5 @@
> -/* Copyright (C) 2012-2020 Free Software Foundation, Inc.
> +/* sysctl function stub.  Common code.
> +   Copyright (C) 1996-2020 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
> @@ -15,6 +16,25 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#if defined __x86_64__ && defined __ILP32__
> -# error "sysctl system call is unsupported in x32 kernel"
> +/* NEED_PRIVATE_SYSCTL needs to be defined before including this file,
> +   either to 0 (no __sysctl symbol) or 1 (__sysctl compat symbol will
> +   be provided).  */
> +
> +#include <errno.h>
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_32)
> +int
> +___sysctl (int *name, int nlen, void *oldval, size_t *oldlenp,
> +	  void *newval, size_t newlen)
> +{
> +  __set_errno (ENOSYS);
> +  return -1;
> +}
> +compat_symbol (libc, ___sysctl, sysctl, GLIBC_2_0);
> +
> +# if NEED_PRIVATE_SYSCTL && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_32)
> +strong_alias (___sysctl, ___sysctl2)
> +compat_symbol (libc, ___sysctl2, __sysctl, GLIBC_2_2);
> +# endif
>  #endif

I don't think this is the correct way to handle compat symbols, since the
idea it keep providing the *same* semantic.  It means that glibc will still
need to continue issue the syscall for alpha, arm, ia64, i686, hppa, mips, 
m68k, microblaze, powerpc, sh, sparc, s390, x86_64.  The ENOSYS compat
could be used on aarch64, csky, riscv64, and nios2 though.

> diff --git a/sysdeps/unix/sysv/linux/sysctl.c b/sysdeps/unix/sysv/linux/sysctl.c
> index 5ea8be8da1..cb958b1588 100644
> --- a/sysdeps/unix/sysv/linux/sysctl.c
> +++ b/sysdeps/unix/sysv/linux/sysctl.c
> @@ -1,4 +1,4 @@
> -/* Read or write system information.  Linux version.
> +/* sysctl function stub.  Legacy version.
>     Copyright (C) 1996-2020 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>  
> @@ -16,26 +16,7 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>  
> -#include <errno.h>
> -#include <linux/sysctl.h>
> -
> -#include <sysdep.h>
> -#include <sys/syscall.h>
> -
> -int
> -__sysctl (int *name, int nlen, void *oldval, size_t *oldlenp,
> -	  void *newval, size_t newlen)
> -{
> -  struct __sysctl_args args =
> -  {
> -    .name = name,
> -    .nlen = nlen,
> -    .oldval = oldval,
> -    .oldlenp = oldlenp,
> -    .newval = newval,
> -    .newlen = newlen
> -  };
> -
> -  return INLINE_SYSCALL (_sysctl, 1, &args);
> -}
> -weak_alias (__sysctl, sysctl)
> +/* The non-generic version also includes the private __sysctl symbol
> +   which was accidentally exported.  */
> +#define NEED_PRIVATE_SYSCTL 1
> +#include <sysdeps/unix/sysv/linux/sysctl-common.h>
> diff --git a/sysdeps/unix/sysv/linux/sysctl.mk b/sysdeps/unix/sysv/linux/sysctl.mk
> deleted file mode 100644
> index 8d04d12e25..0000000000
> --- a/sysdeps/unix/sysv/linux/sysctl.mk
> +++ /dev/null
> @@ -1,3 +0,0 @@
> -# sysctl system call has been deprecated.  It is provided for backward
> -# compatility.  New target shouldn't add it (see x86_64/x32/sysctl.mk).
> -sysdep_routines += sysctl

Ok.

> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/sysctl.c b/sysdeps/unix/sysv/linux/x86_64/x32/sysctl.c
> new file mode 100644
> index 0000000000..88f2f741cf
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/sysctl.c
> @@ -0,0 +1,2 @@
> +/* Despite the old base symbol version, x32 does not have a sysctl
> +   function.  */

Ok.

> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/sysctl.mk b/sysdeps/unix/sysv/linux/x86_64/x32/sysctl.mk
> deleted file mode 100644
> index da018fe624..0000000000
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/sysctl.mk
> +++ /dev/null
> @@ -1 +0,0 @@
> -# X32 doesn't support sysctl.
> 

Ok.
  
Florian Weimer March 11, 2020, 5:48 p.m. UTC | #2
* Adhemerval Zanella via Libc-alpha:

>> +/* The sysctl definition from the generic subdirectory does not
>> +   include the __sysctl compat symbol.  */
>> +#define NEED_PRIVATE_SYSCTL 0
>> +#include <sysdeps/unix/sysv/linux/sysctl-common.h>
>
> Wouldn't be better to define the NEED_PRIVATE_SYSCTL per architecture
> instead and remove this generic file?

Hmm.  Maybe we should use a version-based definition for __sysctl, and
override that for the powerpc64le port?

The removal will not just break builds, but also magically fix some
broken software which incorrectly tries to use sysctl to obtain
randomness, due to a wrong/incomplete port from the BSDs.
  
Zack Weinberg March 11, 2020, 6:17 p.m. UTC | #3
On Wed, Mar 11, 2020 at 1:16 PM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
> On 08/03/2020 18:20, Florian Weimer wrote:
> > The sysctl compat function always fails with ENOSYS because even for
> > architectures which in theory support the system call, it is usually
> > disabled at kernel build time (following the kernel default).
>
> I aleady summarized my take on sysctl deprecation/removal [1], but
> Zack did not reply based on his take to not remove it [2].
>
> And, besides the deprecation done in last release, I foresee that
> the header removal will most likely break some projects. But it should
> not block this change imho.
>
> [1] https://sourceware.org/legacy-ml/libc-alpha/2018-05/msg00067.html
> [2] https://sourceware.org/legacy-ml/libc-alpha/2018-04/msg00633.html

Oof, that was a long time ago.  Let's start over.

Given that the Linux kernel maintainers have made it very clear that
they don't like their implementation of sysctl(2) and they want user
space to stop using it, I have no objection to us changing our
implementation of sysctl(3) to rely exclusively on /proc/sys and other
information sources (e.g. uname(2), getrandom(2)).

However, I think that glibc should continue to provide sysctl(3) and
should actively work to make it more like the fully-supported
sysctl(3) that the BSDs have.  It follows that we should continue to
install <sys/sysctl.h>.  It would be reasonable for us to treat
sysctlbyname() as the primary interface and provide compatibility
MIB-to-name mappings only for the set of MIB vectors that were
historically supported by Linux's sysctl(2).

zw
  
Florian Weimer March 11, 2020, 6:34 p.m. UTC | #4
* Zack Weinberg:

> However, I think that glibc should continue to provide sysctl(3) and
> should actively work to make it more like the fully-supported
> sysctl(3) that the BSDs have.  It follows that we should continue to
> install <sys/sysctl.h>.  It would be reasonable for us to treat
> sysctlbyname() as the primary interface and provide compatibility
> MIB-to-name mappings only for the set of MIB vectors that were
> historically supported by Linux's sysctl(2).

I'm sorry, but I strongly disagree with this.  Our MIBs were never
compatible with the FreeBSD MIBs, resulting in application bugs due to
incomplete porting.  I don't see value in maintaining this interface.
  
Zack Weinberg March 11, 2020, 6:49 p.m. UTC | #5
On Wed, Mar 11, 2020 at 2:36 PM Florian Weimer <fw@deneb.enyo.de> wrote:
> > However, I think that glibc should continue to provide sysctl(3) and
> > should actively work to make it more like the fully-supported
> > sysctl(3) that the BSDs have.  It follows that we should continue to
> > install <sys/sysctl.h>.  It would be reasonable for us to treat
> > sysctlbyname() as the primary interface and provide compatibility
> > MIB-to-name mappings only for the set of MIB vectors that were
> > historically supported by Linux's sysctl(2).
>
> I'm sorry, but I strongly disagree with this.  Our MIBs were never
> compatible with the FreeBSD MIBs, resulting in application bugs due to
> incomplete porting.

To me that's a reason to fix the MIBs to provide source compatibility,
not a reason to scrap the entire idea.  Since the Linux kernel *has*
abandoned the idea, we are free to rearrange things so that
applications that expect the FreeBSD MIBs do in fact work.

> I don't see value in maintaining this interface.

The value I see is principally that 'sysctlbyname("kern.osrelease",
buf, sizeof buf, 0, 0)' is a heck of a lot simpler for applications
than 'int fd = open("/proc/sys/kernel/osrelease"); read(fd, buf,
sizeof(buf)); close(fd)' particularly when you include all of the
error checking, and secondarily that it *could* work when /proc isn't
mounted.  The hypothetical implementation that translated to accessing
files in /proc/sys *wouldn't* work, but if we had it, we could see
more easily whether there was demand.

zw
  
Zack Weinberg March 11, 2020, 8:19 p.m. UTC | #6
On Wed, Mar 11, 2020 at 2:49 PM Zack Weinberg <zackw@panix.com> wrote:
> On Wed, Mar 11, 2020 at 2:36 PM Florian Weimer <fw@deneb.enyo.de> wrote:
> > > However, I think that glibc should continue to provide sysctl(3) and
> > > should actively work to make it more like the fully-supported
> > > sysctl(3) that the BSDs have.  It follows that we should continue to
> > > install <sys/sysctl.h>.  It would be reasonable for us to treat
> > > sysctlbyname() as the primary interface and provide compatibility
> > > MIB-to-name mappings only for the set of MIB vectors that were
> > > historically supported by Linux's sysctl(2).
> >
> > I'm sorry, but I strongly disagree with this.  Our MIBs were never
> > compatible with the FreeBSD MIBs, resulting in application bugs due to
> > incomplete porting.
>
> To me that's a reason to fix the MIBs to provide source compatibility,
> not a reason to scrap the entire idea.  Since the Linux kernel *has*
> abandoned the idea, we are free to rearrange things so that
> applications that expect the FreeBSD MIBs do in fact work.

I looked into this a bit more and concluded that we'd have to do a
whole bunch of research on which MIB vectors would actually be useful
to support.  The existing set of constants for Linux (linux/sysctl.h)
is a mess and may no longer have a straightforward correspondence with
the /proc/sys hierarchy, never mind with FreeBSD or other.  Also, I
had somehow gotten it into my head that we had part of an emulation on
top of /proc already, but in fact we don't.

So I withdraw my objections to your original patch.  We can always put
sys/sysctl.h back in the future if someone does the work to write the
emulation.

zw
  
Vineet Gupta March 12, 2020, 3:49 a.m. UTC | #7
On 3/11/20 1:19 PM, Zack Weinberg wrote:
> So I withdraw my objections to your original patch.  We can always put
> sys/sysctl.h back in the future if someone does the work to write the
> emulation.

My 2 cents. Can we _not_ remove the header per-se. This can certainly cause
arbitrary packages to build time fail (vs. runtime failure from sysctl returning
-1 or some such). Propagation of such fixes in build systems it may take a while.
Consider my personal woe with stime removal in context of Buildroot/busybox.
Despite them fixed in busybox not all moving parts are aligned still and we have
to carry such patches locally to be able to even build glibc 2.31+ there.

ofcourse I'm ignorant to how such things work in glibc in general and in case of
kernel such breakages (of userspace) is considered absolute evil.

Thx,
-Vineet
  
Florian Weimer March 12, 2020, 8:15 a.m. UTC | #8
* Vineet Gupta via Libc-alpha:

> On 3/11/20 1:19 PM, Zack Weinberg wrote:
>> So I withdraw my objections to your original patch.  We can always put
>> sys/sysctl.h back in the future if someone does the work to write the
>> emulation.
>
> My 2 cents. Can we _not_ remove the header per-se. This can certainly cause
> arbitrary packages to build time fail (vs. runtime failure from sysctl returning
> -1 or some such). Propagation of such fixes in build systems it may take a while.
> Consider my personal woe with stime removal in context of Buildroot/busybox.
> Despite them fixed in busybox not all moving parts are aligned still and we have
> to carry such patches locally to be able to even build glibc 2.31+ there.

Why aren't those patches upstream yet?  (I'm not blaming you, I'm just
trying to understand what is going on.)

Are you in a special position becaue you have to use a newer glibc for
your port, and everybody else using this distribution is sticking with
an older glibc?

glibc's approach to removals is inconsistent at best.  stime was never
deprecated and removed directly, for example.  There is also the issue
that configure scripts ignore deprecation warnings, which then can
lead to build issues later one, something that does not happen with
removed interfaces (which are obviously not detected by configure
scripts).

And specific to sysctl, the removal of the header and function
actually fixes bugs in a few packages.
  
Andreas Schwab March 12, 2020, 8:29 a.m. UTC | #9
On Mär 11 2020, Vineet Gupta via Libc-alpha wrote:

> My 2 cents. Can we _not_ remove the header per-se. This can certainly cause
> arbitrary packages to build time fail (vs. runtime failure from sysctl returning
> -1 or some such).

Runtime breakage is worse than compile time breakage, as the latter is
immediately visible and can be fixed right away.

Andreas.
  
Adhemerval Zanella March 12, 2020, 2:33 p.m. UTC | #10
On 12/03/2020 05:15, Florian Weimer wrote:
> * Vineet Gupta via Libc-alpha:
> 
>> On 3/11/20 1:19 PM, Zack Weinberg wrote:
>>> So I withdraw my objections to your original patch.  We can always put
>>> sys/sysctl.h back in the future if someone does the work to write the
>>> emulation.
>>
>> My 2 cents. Can we _not_ remove the header per-se. This can certainly cause
>> arbitrary packages to build time fail (vs. runtime failure from sysctl returning
>> -1 or some such). Propagation of such fixes in build systems it may take a while.
>> Consider my personal woe with stime removal in context of Buildroot/busybox.
>> Despite them fixed in busybox not all moving parts are aligned still and we have
>> to carry such patches locally to be able to even build glibc 2.31+ there.
> 
> Why aren't those patches upstream yet?  (I'm not blaming you, I'm just
> trying to understand what is going on.)
> 
> Are you in a special position becaue you have to use a newer glibc for
> your port, and everybody else using this distribution is sticking with
> an older glibc?
> 
> glibc's approach to removals is inconsistent at best.  stime was never
> deprecated and removed directly, for example.  There is also the issue
> that configure scripts ignore deprecation warnings, which then can
> lead to build issues later one, something that does not happen with
> removed interfaces (which are obviously not detected by configure
> scripts).

stime removal was done without deprecation mainly because it has
been an obsolete function for a long time and it would not make
sense to make a y2038 safe version of it. Since y2038 was not done
for 2.31, maybe we could instead instead had mark it as deprecated
remove it on 2.32 (along with the header).

> 
> And specific to sysctl, the removal of the header and function
> actually fixes bugs in a few packages.
> 

It is always a risk to remove an installed headers and for this
one specifically I agree with you, it is time to move forward 
and stop providing it.
  
Vineet Gupta March 12, 2020, 4:07 p.m. UTC | #11
On 3/12/20 1:15 AM, Florian Weimer wrote:
> * Vineet Gupta via Libc-alpha:
> 
>> On 3/11/20 1:19 PM, Zack Weinberg wrote:
>>> So I withdraw my objections to your original patch.  We can always put
>>> sys/sysctl.h back in the future if someone does the work to write the
>>> emulation.
>>
>> My 2 cents. Can we _not_ remove the header per-se. This can certainly cause
>> arbitrary packages to build time fail (vs. runtime failure from sysctl returning
>> -1 or some such). Propagation of such fixes in build systems it may take a while.
>> Consider my personal woe with stime removal in context of Buildroot/busybox.
>> Despite them fixed in busybox not all moving parts are aligned still and we have
>> to carry such patches locally to be able to even build glibc 2.31+ there.
> 
> Why aren't those patches upstream yet?  (I'm not blaming you, I'm just
> trying to understand what is going on.)

Its mostly logistics. The fixes in busybox was done early but there was no release
(atleast not until I last checked) so buildroot couldn't just bump the package
version. One of my colleagues did send the "patches" to fixup buildroot instead
(essentially backport busybox patches in BR itself) and that got stuck in the
machinery due to some other things.

> Are you in a special position becaue you have to use a newer glibc for
> your port, and everybody else using this distribution is sticking with
> an older glibc?

Thats exactly the case here so I'm in a special situation indeed. Upstream BR is
still with 2.30.x and I needed to test glibc 2.31+ for ARC upstreaming.

> glibc's approach to removals is inconsistent at best.  stime was never
> deprecated and removed directly, for example.  There is also the issue
> that configure scripts ignore deprecation warnings, which then can
> lead to build issues later one, something that does not happen with
> removed interfaces (which are obviously not detected by configure
> scripts).
> 
> And specific to sysctl, the removal of the header and function
> actually fixes bugs in a few packages.
  

Patch

diff --git a/NEWS b/NEWS
index 77631ca707..97be07be31 100644
--- a/NEWS
+++ b/NEWS
@@ -13,7 +13,9 @@  Major new features:
 
 Deprecated and removed features, and other changes affecting compatibility:
 
-  [Add deprecations, removals and changes affecting compatibility here]
+* The deprecated <sys/sysctl.h> header and the sysctl function have been
+  removed.  For compatibility with old binaries, the sysctl function
+  continues to exist, but always fails with ENOSYS.
 
 Changes to build and runtime requirements:
 
diff --git a/include/sys/sysctl.h b/include/sys/sysctl.h
deleted file mode 100644
index fa102aa226..0000000000
--- a/include/sys/sysctl.h
+++ /dev/null
@@ -1,3 +0,0 @@ 
-#ifndef _SYS_SYSCTL_H
-#include_next <sys/sysctl.h>
-#endif  /* _SYS_SYSCTL_H */
diff --git a/manual/sysinfo.texi b/manual/sysinfo.texi
index 4beee0129b..4ca4555443 100644
--- a/manual/sysinfo.texi
+++ b/manual/sysinfo.texi
@@ -14,7 +14,6 @@  can make changes.
 * Platform Type::               Determining operating system and basic
                                   machine type
 * Filesystem Handling::         Controlling/querying mounts
-* System Parameters::           Getting and setting various system parameters
 @end menu
 
 To get information on parameters of the system that are built into the
@@ -1107,146 +1106,3 @@  to zeroes.  It is more widely available than @code{umount2} but since it
 lacks the possibility to forcefully unmount a filesystem is deprecated
 when @code{umount2} is also available.
 @end deftypefun
-
-
-
-@node System Parameters
-@section System Parameters
-
-This section describes the @code{sysctl} function, which gets and sets
-a variety of system parameters.
-
-The symbols used in this section are declared in the file @file{sys/sysctl.h}.
-
-@deftypefun int sysctl (int *@var{names}, int @var{nlen}, void *@var{oldval}, size_t *@var{oldlenp}, void *@var{newval}, size_t @var{newlen})
-@standards{BSD, sys/sysctl.h}
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
-@c Direct syscall, Linux only.
-
-@code{sysctl} gets or sets a specified system parameter.  There are so
-many of these parameters that it is not practical to list them all here,
-but here are some examples:
-
-@itemize @bullet
-@item network domain name
-@item paging parameters
-@item network Address Resolution Protocol timeout time
-@item maximum number of files that may be open
-@item root filesystem device
-@item when kernel was built
-@end itemize
-
-The set of available parameters depends on the kernel configuration and
-can change while the system is running, particularly when you load and
-unload loadable kernel modules.
-
-The system parameters with which @code{sysctl} is concerned are arranged
-in a hierarchical structure like a hierarchical filesystem.  To identify
-a particular parameter, you specify a path through the structure in a
-way analogous to specifying the pathname of a file.  Each component of
-the path is specified by an integer and each of these integers has a
-macro defined for it by @file{sys/sysctl.h}.  @var{names} is the path, in
-the form of an array of integers.  Each component of the path is one
-element of the array, in order.  @var{nlen} is the number of components
-in the path.
-
-For example, the first component of the path for all the paging
-parameters is the value @code{CTL_VM}.  For the free page thresholds, the
-second component of the path is @code{VM_FREEPG}.  So to get the free
-page threshold values, make @var{names} an array containing the two
-elements @code{CTL_VM} and @code{VM_FREEPG} and make @var{nlen} = 2.
-
-
-The format of the value of a parameter depends on the parameter.
-Sometimes it is an integer; sometimes it is an ASCII string; sometimes
-it is an elaborate structure.  In the case of the free page thresholds
-used in the example above, the parameter value is a structure containing
-several integers.
-
-In any case, you identify a place to return the parameter's value with
-@var{oldval} and specify the amount of storage available at that
-location as *@var{oldlenp}.  *@var{oldlenp} does double duty because it
-is also the output location that contains the actual length of the
-returned value.
-
-If you don't want the parameter value returned, specify a null pointer
-for @var{oldval}.
-
-To set the parameter, specify the address and length of the new value
-as @var{newval} and @var{newlen}.  If you don't want to set the parameter,
-specify a null pointer as @var{newval}.
-
-If you get and set a parameter in the same @code{sysctl} call, the value
-returned is the value of the parameter before it was set.
-
-Each system parameter has a set of permissions similar to the
-permissions for a file (including the permissions on directories in its
-path) that determine whether you may get or set it.  For the purposes of
-these permissions, every parameter is considered to be owned by the
-superuser and Group 0 so processes with that effective uid or gid may
-have more access to system parameters.  Unlike with files, the superuser
-does not invariably have full permission to all system parameters, because
-some of them are designed not to be changed ever.
-
-
-@code{sysctl} returns a zero return value if it succeeds.  Otherwise, it
-returns @code{-1} and sets @code{errno} appropriately.  Besides the
-failures that apply to all system calls, the following are the
-@code{errno} codes for all possible failures:
-
-@table @code
-@item EPERM
-The process is not permitted to access one of the components of the
-path of the system parameter or is not permitted to access the system parameter
-itself in the way (read or write) that it requested.
-@c There is some indication in the Linux 2.2 code that the code is trying to
-@c return EACCES here, but the EACCES value never actually makes it to the
-@c user.
-@item ENOTDIR
-There is no system parameter corresponding to @var{name}.
-@item EFAULT
-@var{oldval} is not null, which means the process wanted to read the parameter,
-but *@var{oldlenp} is zero, so there is no place to return it.
-@item EINVAL
-@itemize @bullet
-@item
-The process attempted to set a system parameter to a value that is not valid
-for that parameter.
-@item
-The space provided for the return of the system parameter is not the right
-size for that parameter.
-@end itemize
-@item ENOMEM
-This value may be returned instead of the more correct @code{EINVAL} in some
-cases where the space provided for the return of the system parameter is too
-small.
-
-@end table
-
-@end deftypefun
-
-If you have a Linux kernel with the @code{proc} filesystem, you can get
-and set most of the same parameters by reading and writing to files in
-the @code{sys} directory of the @code{proc} filesystem.  In the @code{sys}
-directory, the directory structure represents the hierarchical structure
-of the parameters.  E.g. you can display the free page thresholds with
-@smallexample
-cat /proc/sys/vm/freepages
-@end smallexample
-@c In Linux, the sysctl() and /proc instances of the parameter are created
-@c together.  The proc filesystem accesses the same data structure as
-@c sysctl(), which has special fields in it for /proc.  But it is still
-@c possible to create a sysctl-only parameter.
-
-Some more traditional and more widely available, though less general,
-@glibcadj{} functions for getting and setting some of the same system
-parameters are:
-
-@itemize @bullet
-@item
-@code{getdomainname}, @code{setdomainname}
-@item
-@code{gethostname}, @code{sethostname} (@xref{Host Identification}.)
-@item
-@code{uname} (@xref{Platform Type}.)
-@end itemize
diff --git a/scripts/check-installed-headers.sh b/scripts/check-installed-headers.sh
index f70340f098..aab56cf405 100644
--- a/scripts/check-installed-headers.sh
+++ b/scripts/check-installed-headers.sh
@@ -74,11 +74,6 @@  for header in "$@"; do
         (finclude/*)
             continue;;
 
-	# sys/sysctl.h produces a deprecation warning and therefore
-	# fails compilation with -Werror.
-	(sys/sysctl.h)
-	    continue;;
-
         # sys/vm86.h is "unsupported on x86-64" and errors out on that target.
         (sys/vm86.h)
             case "$is_x86_64" in
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 60dc5cf9e5..089a4899d5 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -54,9 +54,7 @@  CFLAGS-malloc.c += -DMORECORE_CLEARS=2
 endif
 
 ifeq ($(subdir),misc)
-include $(firstword $(wildcard $(sysdirs:=/sysctl.mk)))
-
-sysdep_routines += adjtimex clone umount umount2 readahead \
+sysdep_routines += adjtimex clone umount umount2 readahead sysctl \
 		   setfsuid setfsgid epoll_pwait signalfd \
 		   eventfd eventfd_read eventfd_write prlimit \
 		   personality epoll_wait tee vmsplice splice \
@@ -71,7 +69,7 @@  CFLAGS-open_by_handle_at.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-sync_file_range.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-tst-writev.c += "-DARTIFICIAL_LIMIT=(0x80000000-sysconf(_SC_PAGESIZE))"
 
-sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
+sysdep_headers += sys/mount.h sys/acct.h \
 		  sys/klog.h \
 		  sys/user.h sys/prctl.h \
 		  sys/kd.h sys/soundcard.h sys/vt.h \
@@ -81,7 +79,7 @@  sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
 		  bits/a.out.h sys/inotify.h sys/signalfd.h sys/eventfd.h \
 		  sys/timerfd.h sys/fanotify.h bits/eventfd.h bits/inotify.h \
 		  bits/signalfd.h bits/timerfd.h bits/epoll.h \
-		  bits/socket_type.h bits/syscall.h bits/sysctl.h \
+		  bits/socket_type.h bits/syscall.h \
 		  bits/mman-linux.h bits/mman-shared.h bits/ptrace-shared.h \
 		  bits/siginfo-arch.h bits/siginfo-consts-arch.h \
 		  bits/procfs.h bits/procfs-id.h bits/procfs-extra.h \
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index d385085c61..9a58dda9f2 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -177,6 +177,8 @@  libc {
   GLIBC_2.30 {
     getdents64; gettid; tgkill;
   }
+  GLIBC_2.32 {
+  }
   GLIBC_PRIVATE {
     # functions used in other libraries
     __syscall_rt_sigqueueinfo;
diff --git a/sysdeps/unix/sysv/linux/bits/sysctl.h b/sysdeps/unix/sysv/linux/bits/sysctl.h
deleted file mode 100644
index 81447b2f74..0000000000
--- a/sysdeps/unix/sysv/linux/bits/sysctl.h
+++ /dev/null
@@ -1 +0,0 @@ 
-/* Empty file.  */
diff --git a/sysdeps/unix/sysv/linux/generic/sysctl.c b/sysdeps/unix/sysv/linux/generic/sysctl.c
index e7d5a3cf93..c2ca30268b 100644
--- a/sysdeps/unix/sysv/linux/generic/sysctl.c
+++ b/sysdeps/unix/sysv/linux/generic/sysctl.c
@@ -1,6 +1,6 @@ 
-/* Copyright (C) 2011-2020 Free Software Foundation, Inc.
+/* sysctl function stub.  generic subdirectory version.
+   Copyright (C) 1996-2020 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -13,20 +13,10 @@ 
    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
+   License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-/* This deprecated syscall is no longer used (replaced with /proc/sys).  */
-int
-sysctl (int *name, int nlen, void *oldval, size_t *oldlenp,
-        void *newval, size_t newlen)
-{
-  __set_errno (ENOSYS);
-  return -1;
-}
-stub_warning (sysctl)
+/* The sysctl definition from the generic subdirectory does not
+   include the __sysctl compat symbol.  */
+#define NEED_PRIVATE_SYSCTL 0
+#include <sysdeps/unix/sysv/linux/sysctl-common.h>
diff --git a/sysdeps/unix/sysv/linux/sys/sysctl.h b/sysdeps/unix/sysv/linux/sys/sysctl.h
deleted file mode 100644
index 1ead597244..0000000000
--- a/sysdeps/unix/sysv/linux/sys/sysctl.h
+++ /dev/null
@@ -1,76 +0,0 @@ 
-/* Copyright (C) 1996-2020 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
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef	_SYS_SYSCTL_H
-#define	_SYS_SYSCTL_H	1
-
-#warning "The <sys/sysctl.h> header is deprecated and will be removed."
-
-#include <features.h>
-#define __need_size_t
-#include <stddef.h>
-/* Prevent more kernel headers than necessary to be included.  */
-#ifndef _LINUX_KERNEL_H
-# define _LINUX_KERNEL_H	1
-# define __undef_LINUX_KERNEL_H
-#endif
-#ifndef _LINUX_TYPES_H
-# define _LINUX_TYPES_H		1
-# define __undef_LINUX_TYPES_H
-#endif
-#ifndef _LINUX_LIST_H
-# define _LINUX_LIST_H		1
-# define __undef_LINUX_LIST_H
-#endif
-#ifndef __LINUX_COMPILER_H
-# define __LINUX_COMPILER_H	1
-# define __user
-# define __undef__LINUX_COMPILER_H
-#endif
-
-#include <linux/sysctl.h>
-
-#ifdef __undef_LINUX_KERNEL_H
-# undef _LINUX_KERNEL_H
-# undef __undef_LINUX_KERNEL_H
-#endif
-#ifdef __undef_LINUX_TYPES_H
-# undef _LINUX_TYPES_H
-# undef __undef_LINUX_TYPES_H
-#endif
-#ifdef __undef_LINUX_LIST_H
-# undef _LINUX_LIST_H
-# undef __undef_LINUX_LIST_H
-#endif
-#ifdef __undef__LINUX_COMPILER_H
-# undef __LINUX_COMPILER_H
-# undef __user
-# undef __undef__LINUX_COMPILER_H
-#endif
-
-#include <bits/sysctl.h>
-
-__BEGIN_DECLS
-
-/* Read or write system parameters.  */
-extern int sysctl (int *__name, int __nlen, void *__oldval,
-		   size_t *__oldlenp, void *__newval, size_t __newlen) __THROW
-  __attribute_deprecated__;
-
-__END_DECLS
-
-#endif	/* _SYS_SYSCTL_H */
diff --git a/sysdeps/unix/sysv/linux/x86/bits/sysctl.h b/sysdeps/unix/sysv/linux/sysctl-common.h
similarity index 50%
rename from sysdeps/unix/sysv/linux/x86/bits/sysctl.h
rename to sysdeps/unix/sysv/linux/sysctl-common.h
index 873a2af109..84ace6ee67 100644
--- a/sysdeps/unix/sysv/linux/x86/bits/sysctl.h
+++ b/sysdeps/unix/sysv/linux/sysctl-common.h
@@ -1,4 +1,5 @@ 
-/* Copyright (C) 2012-2020 Free Software Foundation, Inc.
+/* sysctl function stub.  Common code.
+   Copyright (C) 1996-2020 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
@@ -15,6 +16,25 @@ 
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if defined __x86_64__ && defined __ILP32__
-# error "sysctl system call is unsupported in x32 kernel"
+/* NEED_PRIVATE_SYSCTL needs to be defined before including this file,
+   either to 0 (no __sysctl symbol) or 1 (__sysctl compat symbol will
+   be provided).  */
+
+#include <errno.h>
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_32)
+int
+___sysctl (int *name, int nlen, void *oldval, size_t *oldlenp,
+	  void *newval, size_t newlen)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+compat_symbol (libc, ___sysctl, sysctl, GLIBC_2_0);
+
+# if NEED_PRIVATE_SYSCTL && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_32)
+strong_alias (___sysctl, ___sysctl2)
+compat_symbol (libc, ___sysctl2, __sysctl, GLIBC_2_2);
+# endif
 #endif
diff --git a/sysdeps/unix/sysv/linux/sysctl.c b/sysdeps/unix/sysv/linux/sysctl.c
index 5ea8be8da1..cb958b1588 100644
--- a/sysdeps/unix/sysv/linux/sysctl.c
+++ b/sysdeps/unix/sysv/linux/sysctl.c
@@ -1,4 +1,4 @@ 
-/* Read or write system information.  Linux version.
+/* sysctl function stub.  Legacy version.
    Copyright (C) 1996-2020 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,26 +16,7 @@ 
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <linux/sysctl.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-int
-__sysctl (int *name, int nlen, void *oldval, size_t *oldlenp,
-	  void *newval, size_t newlen)
-{
-  struct __sysctl_args args =
-  {
-    .name = name,
-    .nlen = nlen,
-    .oldval = oldval,
-    .oldlenp = oldlenp,
-    .newval = newval,
-    .newlen = newlen
-  };
-
-  return INLINE_SYSCALL (_sysctl, 1, &args);
-}
-weak_alias (__sysctl, sysctl)
+/* The non-generic version also includes the private __sysctl symbol
+   which was accidentally exported.  */
+#define NEED_PRIVATE_SYSCTL 1
+#include <sysdeps/unix/sysv/linux/sysctl-common.h>
diff --git a/sysdeps/unix/sysv/linux/sysctl.mk b/sysdeps/unix/sysv/linux/sysctl.mk
deleted file mode 100644
index 8d04d12e25..0000000000
--- a/sysdeps/unix/sysv/linux/sysctl.mk
+++ /dev/null
@@ -1,3 +0,0 @@ 
-# sysctl system call has been deprecated.  It is provided for backward
-# compatility.  New target shouldn't add it (see x86_64/x32/sysctl.mk).
-sysdep_routines += sysctl
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/sysctl.c b/sysdeps/unix/sysv/linux/x86_64/x32/sysctl.c
new file mode 100644
index 0000000000..88f2f741cf
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/sysctl.c
@@ -0,0 +1,2 @@ 
+/* Despite the old base symbol version, x32 does not have a sysctl
+   function.  */
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/sysctl.mk b/sysdeps/unix/sysv/linux/x86_64/x32/sysctl.mk
deleted file mode 100644
index da018fe624..0000000000
--- a/sysdeps/unix/sysv/linux/x86_64/x32/sysctl.mk
+++ /dev/null
@@ -1 +0,0 @@ 
-# X32 doesn't support sysctl.