diff mbox series

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

Message ID 87k13opf3h.fsf@mid.deneb.enyo.de
State New
Headers show
Series [v2] Linux: Remove <sys/sysctl.h> and the sysctl function | expand

Commit Message

Florian Weimer March 13, 2020, 1:19 p.m. UTC
This version changes the way the discrepancy around the GLIBC_2.17
base symbol version is handled.  The generic (directory) version
sysctl.c version is folded into the default Linux implementation, with
overrides for powerpc64le and microblaze.

Tested on i686-linux-gnu and x86_64-linux-gnu.  Built with
build-many-glibcs.py.

8<------------------------------------------------------------------8<
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.

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 -
 .../{x86/bits/sysctl.h => microblaze/sysctl.c}     |  15 ++-
 .../{generic => powerpc/powerpc64/le}/sysctl.c     |  31 ++---
 sysdeps/unix/sysv/linux/sys/sysctl.h               |  76 -----------
 sysdeps/unix/sysv/linux/sysctl.c                   |  35 +++--
 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, 51 insertions(+), 279 deletions(-)

Comments

develop--- via Libc-alpha March 13, 2020, 5:50 p.m. UTC | #1
On 13/03/2020 10:19, Florian Weimer wrote:
> diff --git a/sysdeps/unix/sysv/linux/sysctl.c b/sysdeps/unix/sysv/linux/sysctl.c
> index 5ea8be8da1..389b958226 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.
>     Copyright (C) 1996-2020 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>  
> @@ -17,25 +17,20 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #include <errno.h>
> -#include <linux/sysctl.h>
> +#include <shlib-compat.h>
>  
> -#include <sysdep.h>
> -#include <sys/syscall.h>
> -
> -int
> -__sysctl (int *name, int nlen, void *oldval, size_t *oldlenp,
> -	  void *newval, size_t newlen)
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_32)
> +int attribute_compat_text_section
> +___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);
> +  __set_errno (ENOSYS);
> +  return -1;
>  }
> -weak_alias (__sysctl, sysctl)
> +compat_symbol (libc, ___sysctl, sysctl, GLIBC_2_0);
> +
> +# if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
> +strong_alias (___sysctl, ___sysctl2)
> +compat_symbol (libc, ___sysctl2, __sysctl, GLIBC_2_2);
> +# endif
> +#endif

I still think we should keep the syscall call on compat symbol
for architecture that do not return ENOSYS.
Florian Weimer March 13, 2020, 5:53 p.m. UTC | #2
* Adhemerval Zanella via Libc-alpha:

> I still think we should keep the syscall call on compat symbol
> for architecture that do not return ENOSYS.

The kernel will return ENOSYS instead because support for the system
call is optional it is almost never compiled in, as far as I know.
develop--- via Libc-alpha March 13, 2020, 6:53 p.m. UTC | #3
On 13/03/2020 14:53, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> I still think we should keep the syscall call on compat symbol
>> for architecture that do not return ENOSYS.
> 
> The kernel will return ENOSYS instead because support for the system
> call is optional it is almost never compiled in, as far as I know.
> 

What I am seeing is with the sysctl example from man-pages is:

               aarch64: !SYS__sysctl
                 alpha: ENOSYS
                   arm: OK		(4.12.13)
                  hppa: ?
                  i686: OK		(4.15.0-54-generic)
                  ia64: ENOSYS
                  m68k: ENOSYS
            microblaze: ?
                  mips: ENOSYS
                mips64: ENOSYS
            mips64-n32: ENOSYS
                 nios2: !SYS__sysctl
               powerpc: ENOSYS
             powerpc64: ENOSYS
           powerpc64le: ENOSYS
               riscv64: !SYS__sysctl
                  s390: OK		(4.12.14-197.21-default)
                 s390x: OK		(4.12.14-197.21-default)
                   sh4: ENOSYS
               sparc64: ENOSYS
               sparcv9: ENOSYS
                x86_64: OK		(4.15.0-54-generic)
            x86_64-x32: FAIL

With !SYS__sysctl being the __NR__sysctl not being defined in
sys/syscall.h, ENOSYS is kernel return is, OK is the syscall
does returns information, and '?' where __NR__sysctl is define
but I don't have a way to test with a running kernel.

So it seems that at least for arm, i686, x86_64, s390, and
s390x the syscall does work.
Florian Weimer March 25, 2020, 9:18 a.m. UTC | #4
* Adhemerval Zanella via Libc-alpha:

> On 13/03/2020 14:53, Florian Weimer wrote:
>> * Adhemerval Zanella via Libc-alpha:
>> 
>>> I still think we should keep the syscall call on compat symbol
>>> for architecture that do not return ENOSYS.
>> 
>> The kernel will return ENOSYS instead because support for the system
>> call is optional it is almost never compiled in, as far as I know.
>> 
>
> What I am seeing is with the sysctl example from man-pages is:
>
>                aarch64: !SYS__sysctl
>                  alpha: ENOSYS
>                    arm: OK		(4.12.13)
>                   hppa: ?
>                   i686: OK		(4.15.0-54-generic)
>                   ia64: ENOSYS
>                   m68k: ENOSYS
>             microblaze: ?
>                   mips: ENOSYS
>                 mips64: ENOSYS
>             mips64-n32: ENOSYS
>                  nios2: !SYS__sysctl
>                powerpc: ENOSYS
>              powerpc64: ENOSYS
>            powerpc64le: ENOSYS
>                riscv64: !SYS__sysctl
>                   s390: OK		(4.12.14-197.21-default)
>                  s390x: OK		(4.12.14-197.21-default)
>                    sh4: ENOSYS
>                sparc64: ENOSYS
>                sparcv9: ENOSYS
>                 x86_64: OK		(4.15.0-54-generic)
>             x86_64-x32: FAIL
>
> With !SYS__sysctl being the __NR__sysctl not being defined in
> sys/syscall.h, ENOSYS is kernel return is, OK is the syscall
> does returns information, and '?' where __NR__sysctl is define
> but I don't have a way to test with a running kernel.
>
> So it seems that at least for arm, i686, x86_64, s390, and
> s390x the syscall does work.

Is this the Ubuntu distribution kernel?  It overrides the upstream
kernel defaults, unlike most other distributions.  I don't think
that's a good indicator of actual use.

Worst case, Ubuntu can carry a custom patch to re-enable sysctl if
they need it.
develop--- via Libc-alpha March 25, 2020, 12:37 p.m. UTC | #5
On 25/03/2020 06:18, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> On 13/03/2020 14:53, Florian Weimer wrote:
>>> * Adhemerval Zanella via Libc-alpha:
>>>
>>>> I still think we should keep the syscall call on compat symbol
>>>> for architecture that do not return ENOSYS.
>>>
>>> The kernel will return ENOSYS instead because support for the system
>>> call is optional it is almost never compiled in, as far as I know.
>>>
>>
>> What I am seeing is with the sysctl example from man-pages is:
>>
>>                aarch64: !SYS__sysctl
>>                  alpha: ENOSYS
>>                    arm: OK		(4.12.13)
>>                   hppa: ?
>>                   i686: OK		(4.15.0-54-generic)
>>                   ia64: ENOSYS
>>                   m68k: ENOSYS
>>             microblaze: ?
>>                   mips: ENOSYS
>>                 mips64: ENOSYS
>>             mips64-n32: ENOSYS
>>                  nios2: !SYS__sysctl
>>                powerpc: ENOSYS
>>              powerpc64: ENOSYS
>>            powerpc64le: ENOSYS
>>                riscv64: !SYS__sysctl
>>                   s390: OK		(4.12.14-197.21-default)
>>                  s390x: OK		(4.12.14-197.21-default)
>>                    sh4: ENOSYS
>>                sparc64: ENOSYS
>>                sparcv9: ENOSYS
>>                 x86_64: OK		(4.15.0-54-generic)
>>             x86_64-x32: FAIL
>>
>> With !SYS__sysctl being the __NR__sysctl not being defined in
>> sys/syscall.h, ENOSYS is kernel return is, OK is the syscall
>> does returns information, and '?' where __NR__sysctl is define
>> but I don't have a way to test with a running kernel.
>>
>> So it seems that at least for arm, i686, x86_64, s390, and
>> s390x the syscall does work.
> 
> Is this the Ubuntu distribution kernel?  It overrides the upstream
> kernel defaults, unlike most other distributions.  I don't think
> that's a good indicator of actual use.

The x86_64/i686 and arm is a Ubuntu kernel, the s390x is a SLES
one. But kernel does used to provide sysctl syscall up to version 
2.6.36 (CONFIG_SYSCTL_SYSCALL was removed by
8b1bb90701f9a51f10ce8a990bcc1e237cb3b1c7). 

My impression is this change might characterize a 'don't break user 
space' issue, but I am not exactly sure why the kernel developers
had done it. Neither why Ubuntu/SUSE guys has explicit enable it on 
recent kernels.

> 
> Worst case, Ubuntu can carry a custom patch to re-enable sysctl if
> they need it.
>
Florian Weimer April 14, 2020, 12:22 p.m. UTC | #6
* Adhemerval Zanella via Libc-alpha:

> My impression is this change might characterize a 'don't break user 
> space' issue, but I am not exactly sure why the kernel developers
> had done it. Neither why Ubuntu/SUSE guys has explicit enable it on 
> recent kernels.

That ship has sailed:

commit 61a47c1ad3a4dc6882f01ebdc88138ac62d0df03
Author: Eric W. Biederman <ebiederm@xmission.com>
Date:   Tue Oct 1 13:01:19 2019 -0500

    sysctl: Remove the sysctl system call
    
    This system call has been deprecated almost since it was introduced, and
    in a survey of the linux distributions I can no longer find any of them
    that enable CONFIG_SYSCTL_SYSCALL.  The only indication that I can find
    that anyone might care is that a few of the defconfigs in the kernel
    enable CONFIG_SYSCTL_SYSCALL.  However this appears in only 31 of 414
    defconfigs in the kernel, so I suspect this symbols presence is simply
    because it is harmless to include rather than because it is necessary.
    
    As there appear to be no users of the sysctl system call, remove the
    code.  As this removes one of the few uses of the internal kernel mount
    of proc I hope this allows for even more simplifications of the proc
    filesystem.

That commit went into Linux 5.4.

I believe that as a result, we might as well stub out the system call
in glibc.  Do you agree?
diff mbox series

Patch

diff --git a/NEWS b/NEWS
index e0379fc53c..a9169d5c4c 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/x86/bits/sysctl.h b/sysdeps/unix/sysv/linux/microblaze/sysctl.c
similarity index 66%
rename from sysdeps/unix/sysv/linux/x86/bits/sysctl.h
rename to sysdeps/unix/sysv/linux/microblaze/sysctl.c
index 873a2af109..d35dd8ef1e 100644
--- a/sysdeps/unix/sysv/linux/x86/bits/sysctl.h
+++ b/sysdeps/unix/sysv/linux/microblaze/sysctl.c
@@ -1,4 +1,5 @@ 
-/* Copyright (C) 2012-2020 Free Software Foundation, Inc.
+/* sysctl function stub.  microblaze version.
+   Copyright (C) 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,14 @@ 
    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"
+/* microblaze is special because it has an ABI baseline of 2.18, but
+   still includes the __sysctl symbol.  */
+
+#ifdef SHARED
+
+# include <sysdeps/unix/sysv/linux/sysctl.c>
+
+strong_alias (___sysctl, ___sysctl2)
+compat_symbol (libc, ___sysctl2, __sysctl, GLIBC_2_2);
+
 #endif
diff --git a/sysdeps/unix/sysv/linux/generic/sysctl.c b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/sysctl.c
similarity index 58%
rename from sysdeps/unix/sysv/linux/generic/sysctl.c
rename to sysdeps/unix/sysv/linux/powerpc/powerpc64/le/sysctl.c
index e7d5a3cf93..25203e4aa4 100644
--- a/sysdeps/unix/sysv/linux/generic/sysctl.c
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/sysctl.c
@@ -1,6 +1,6 @@ 
-/* Copyright (C) 2011-2020 Free Software Foundation, Inc.
+/* sysctl function stub.  powerpc64le version.
+   Copyright (C) 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,17 @@ 
    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)
+/* powerpc64le is special because it has an ABI baseline of 2.17, but
+   still includes the __sysctl symbol.  */
+
+#ifdef SHARED
+
+# include <sysdeps/unix/sysv/linux/sysctl.c>
+
+strong_alias (___sysctl, ___sysctl2)
+compat_symbol (libc, ___sysctl2, __sysctl, GLIBC_2_2);
+
+#endif
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/sysctl.c b/sysdeps/unix/sysv/linux/sysctl.c
index 5ea8be8da1..389b958226 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.
    Copyright (C) 1996-2020 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -17,25 +17,20 @@ 
    <https://www.gnu.org/licenses/>.  */
 
 #include <errno.h>
-#include <linux/sysctl.h>
+#include <shlib-compat.h>
 
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-int
-__sysctl (int *name, int nlen, void *oldval, size_t *oldlenp,
-	  void *newval, size_t newlen)
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_32)
+int attribute_compat_text_section
+___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);
+  __set_errno (ENOSYS);
+  return -1;
 }
-weak_alias (__sysctl, sysctl)
+compat_symbol (libc, ___sysctl, sysctl, GLIBC_2_0);
+
+# if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (___sysctl, ___sysctl2)
+compat_symbol (libc, ___sysctl2, __sysctl, GLIBC_2_2);
+# endif
+#endif
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.