diff options
-rw-r--r-- | gnu/local.mk | 1 | ||||
-rw-r--r-- | gnu/packages/base.scm | 3 | ||||
-rw-r--r-- | gnu/packages/patches/glibc-reinstate-prlimit64-fallback.patch | 127 |
3 files changed, 130 insertions, 1 deletions
diff --git a/gnu/local.mk b/gnu/local.mk index 024a77143b..78bad98918 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -723,6 +723,7 @@ dist_patch_DATA = \ %D%/packages/patches/glibc-locales.patch \ %D%/packages/patches/glibc-memchr-overflow-i686.patch \ %D%/packages/patches/glibc-o-largefile.patch \ + %D%/packages/patches/glibc-reinstate-prlimit64-fallback.patch \ %D%/packages/patches/glibc-vectorized-strcspn-guards.patch \ %D%/packages/patches/glibc-versioned-locpath.patch \ %D%/packages/patches/glibc-2.27-git-fixes.patch \ diff --git a/gnu/packages/base.scm b/gnu/packages/base.scm index adab0e1420..a65e932df4 100644 --- a/gnu/packages/base.scm +++ b/gnu/packages/base.scm @@ -568,7 +568,8 @@ store.") "glibc-2.27-git-fixes.patch" "glibc-hidden-visibility-ldconfig.patch" "glibc-versioned-locpath.patch" - "glibc-allow-kernel-2.6.32.patch")))) + "glibc-allow-kernel-2.6.32.patch" + "glibc-reinstate-prlimit64-fallback.patch")))) (build-system gnu-build-system) ;; Glibc's <limits.h> refers to <linux/limit.h>, for instance, so glibc diff --git a/gnu/packages/patches/glibc-reinstate-prlimit64-fallback.patch b/gnu/packages/patches/glibc-reinstate-prlimit64-fallback.patch new file mode 100644 index 0000000000..ccc153c12a --- /dev/null +++ b/gnu/packages/patches/glibc-reinstate-prlimit64-fallback.patch @@ -0,0 +1,127 @@ +This patch reinstates fallback code when the 'prlimit64' system call is +missing by reverting the relevant part of this upstream commit: + + commit 695d7d138eda449678a1650a8b8b58181033353f + Author: Joseph Myers <joseph@codesourcery.com> + Date: Tue May 9 14:05:09 2017 +0000 + + Assume prlimit64 is available. + +The fallback code is useful on systems that lack 'prlimit64', such as the +2.6.32-on-steroid kernel found on RHEL 6: + + <https://lists.gnu.org/archive/html/guix-devel/2018-03/msg00349.html> + +diff --git a/sysdeps/unix/sysv/linux/getrlimit64.c b/sysdeps/unix/sysv/linux/getrlimit64.c +index 37c173286f..56af3c0646 100644 +--- b/sysdeps/unix/sysv/linux/getrlimit64.c ++++ a/sysdeps/unix/sysv/linux/getrlimit64.c +@@ -35,7 +35,40 @@ + int + __getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits) + { +- return INLINE_SYSCALL_CALL (prlimit64, 0, resource, NULL, rlimits); ++#ifdef __NR_prlimit64 ++ int res = INLINE_SYSCALL_CALL (prlimit64, 0, resource, NULL, rlimits); ++ if (res == 0 || errno != ENOSYS) ++ return res; ++#endif ++ ++/* The fallback code only makes sense if the platform supports either ++ __NR_ugetrlimit and/or __NR_getrlimit. */ ++#if defined (__NR_ugetrlimit) || defined (__NR_getrlimit) ++# ifndef __NR_ugetrlimit ++# define __NR_ugetrlimit __NR_getrlimit ++# endif ++# if __RLIM_T_MATCHES_RLIM64_T ++# define rlimits32 (*rlimits) ++# else ++ struct rlimit rlimits32; ++# endif ++ ++ if (INLINE_SYSCALL_CALL (ugetrlimit, resource, &rlimits32) < 0) ++ return -1; ++ ++# if !__RLIM_T_MATCHES_RLIM64_T ++ if (rlimits32.rlim_cur == RLIM_INFINITY) ++ rlimits->rlim_cur = RLIM64_INFINITY; ++ else ++ rlimits->rlim_cur = rlimits32.rlim_cur; ++ if (rlimits32.rlim_max == RLIM_INFINITY) ++ rlimits->rlim_max = RLIM64_INFINITY; ++ else ++ rlimits->rlim_max = rlimits32.rlim_max; ++# endif /* !__RLIM_T_MATCHES_RLIM64_T */ ++#endif /* defined (__NR_ugetrlimit) || defined (__NR_getrlimit) */ ++ ++ return 0; + } + libc_hidden_def (__getrlimit64) + +diff --git a/sysdeps/unix/sysv/linux/setrlimit.c b/sysdeps/unix/sysv/linux/setrlimit.c +index 01812ac355..8773c78236 100644 +--- b/sysdeps/unix/sysv/linux/setrlimit.c ++++ a/sysdeps/unix/sysv/linux/setrlimit.c +@@ -34,6 +34,7 @@ + int + __setrlimit (enum __rlimit_resource resource, const struct rlimit *rlim) + { ++# ifdef __NR_prlimit64 + struct rlimit64 rlim64; + + if (rlim->rlim_cur == RLIM_INFINITY) +@@ -45,7 +46,11 @@ + else + rlim64.rlim_max = rlim->rlim_max; + +- return INLINE_SYSCALL_CALL (prlimit64, 0, resource, &rlim64, NULL); ++ int res = INLINE_SYSCALL_CALL (prlimit64, 0, resource, &rlim64, NULL); ++ if (res == 0 || errno != ENOSYS) ++ return res; ++# endif ++ return INLINE_SYSCALL_CALL (setrlimit, resource, rlim); + } + + # if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) +diff --git a/sysdeps/unix/sysv/linux/setrlimit64.c b/sysdeps/unix/sysv/linux/setrlimit64.c +index 2dd129d99e..db1960fc18 100644 +--- b/sysdeps/unix/sysv/linux/setrlimit64.c ++++ a/sysdeps/unix/sysv/linux/setrlimit64.c +@@ -36,7 +36,36 @@ + int + __setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits) + { +- return INLINE_SYSCALL_CALL (prlimit64, 0, resource, rlimits, NULL); ++ int res; ++ ++#ifdef __NR_prlimit64 ++ res = INLINE_SYSCALL_CALL (prlimit64, 0, resource, rlimits, NULL); ++ if (res == 0 || errno != ENOSYS) ++ return res; ++#endif ++ ++/* The fallback code only makes sense if the platform supports ++ __NR_setrlimit. */ ++#ifdef __NR_setrlimit ++# if !__RLIM_T_MATCHES_RLIM64_T ++ struct rlimit rlimits32; ++ ++ if (rlimits->rlim_cur >= RLIM_INFINITY) ++ rlimits32.rlim_cur = RLIM_INFINITY; ++ else ++ rlimits32.rlim_cur = rlimits->rlim_cur; ++ if (rlimits->rlim_max >= RLIM_INFINITY) ++ rlimits32.rlim_max = RLIM_INFINITY; ++ else ++ rlimits32.rlim_max = rlimits->rlim_max; ++# else ++# define rlimits32 (*rlimits) ++# endif ++ ++ res = INLINE_SYSCALL_CALL (setrlimit, resource, &rlimits32); ++#endif ++ ++ return res; + } + weak_alias (__setrlimit64, setrlimit64) + |