This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] Consolidate Linux setrlimit and getrlimit implementation
- From: Yury Norov <ynorov at caviumnetworks dot com>
- To: Adhemerval Zanella <adhemerval dot zanella at linaro dot org>
- Cc: <libc-alpha at sourceware dot org>
- Date: Fri, 21 Oct 2016 20:21:51 +0300
- Subject: Re: [PATCH] Consolidate Linux setrlimit and getrlimit implementation
- Authentication-results: sourceware.org; auth=none
- Authentication-results: spf=none (sender IP is ) smtp.mailfrom=Yuri dot Norov at caviumnetworks dot com;
- References: <1477068711-6825-1-git-send-email-adhemerval.zanella@linaro.org>
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
On Fri, Oct 21, 2016 at 02:51:51PM -0200, Adhemerval Zanella wrote:
> This patch consolidates all Linux setrlimit and getrlimit on the default
> sysdeps/unix/sysv/linux/{set,get}rlimit{64}.c. It contains two exceptions:
>
> 1. mips32 and mips64n32 which requires a versioned symbol for GLIBC 2.19
> and higher due a broken RLIM64_INFINITY constant.
> 2. sparc32 does not define a compat symbol for getrlimit64 for old 2GB
> limit. I am not sure if it is required, but a RLIM_INFINITY fix [1]
> change its definition without adding a compat symbol. This patch does
> not aim to address this possible issue, it follow current symbol
> export.
>
> The default implementation uses prlimit64 for 64 bit rlim_t ({set,get}rlimit64)
> and if it fails with ENOSYS it fall back to {get,set}rlimit syscall. This
> code path is only used on kernel older than 2.6.36 (basically now only x86)
> and I avoid to user __ASSUME_PRLIMTI64 to simplify the implementation. Once
> x86 moves to be on par with other architectures regarding minimum kernel
> supported we can get rid of using old syscalls and default path.
>
> A new type size define is added, __RLIM_T_MATCHES_RLIM64_T, where is set as
> default for 64 bits ports. This allows the default implementation to avoid
> {get,set}rlimit building and alias {get,set}rlimit64 to {get,set}rlimit.
>
> Checked on x86_64, i386, armhf, aarch64, and powerpc64le. I also did a
> sanity build plus check-abi on all other supported architectures.
Also checked on aarch64/ilp32
> diff --git a/sysdeps/unix/sysv/linux/setrlimit64.c b/sysdeps/unix/sysv/linux/setrlimit64.c
> index 5f444d2..ce5429e 100644
> --- a/sysdeps/unix/sysv/linux/setrlimit64.c
> +++ b/sysdeps/unix/sysv/linux/setrlimit64.c
> @@ -1,4 +1,5 @@
> -/* Copyright (C) 2010-2016 Free Software Foundation, Inc.
> +/* Linux setrlimit64 implementation (64 bits off_t).
> + Copyright (C) 2010-2016 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
> @@ -16,25 +17,30 @@
> <http://www.gnu.org/licenses/>. */
>
> #include <errno.h>
> -#include <sys/resource.h>
> #include <sys/types.h>
> -#include <sysdep.h>
> -#include <kernel-features.h>
> +#include <shlib-compat.h>
> +
> +/* Add this redirection so the strong_alias for __RLIM_T_MATCHES_RLIM64_T
> + linking setlimit64 to {__}setrlimit does not thrown a type error. */
> +#undef settrlimit
> +#undef __sttrlimit
> +#define setrlimit setrlimit_redirect
> +#define __setrlimit __setrlimit_redirect
> +#include <sys/resource.h>
> +#undef setrlimit
> +#undef __setrlimit
>
> /* Set the soft and hard limits for RESOURCE to *RLIMITS.
> Only the super-user can increase hard limits.
> Return 0 if successful, -1 if not (and sets errno). */
> int
> -setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits)
> +__setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits)
> {
> -#ifdef __ASSUME_PRLIMIT64
> - return INLINE_SYSCALL (prlimit64, 4, 0, resource, rlimits, NULL);
> -#else
> -# ifdef __NR_prlimit64
> - int res = INLINE_SYSCALL (prlimit64, 4, 0, resource, rlimits, NULL);
> +#ifdef __NR_prlimit64
> + int res = INLINE_SYSCALL_CALL (prlimit64, 0, resource, rlimits, NULL);
> if (res == 0 || errno != ENOSYS)
> return res;
> -# endif
> +#endif
> struct rlimit rlimits32;
If __RLIM_T_MATCHES_RLIM64_T is defined, you can bypass conversion.
>
> if (rlimits->rlim_cur >= RLIM_INFINITY)
> @@ -46,6 +52,11 @@ setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits)
> else
> rlimits32.rlim_max = rlimits->rlim_max;
>
> - return __setrlimit (resource, &rlimits32);
> -#endif
> + return INLINE_SYSCALL_CALL (setrlimit, resource, &rlimits32);
> }
> +weak_alias (__setrlimit64, setrlimit64)
> +
> +#ifdef __RLIM_T_MATCHES_RLIM64_T
> +strong_alias (__setrlimit64, __setrlimit)
> +weak_alias (__setrlimit64, setrlimit)
> +#endif