Check for VM limit RPCs
* config.h.in: add #undef for HAVE_MACH_VM_GET_SIZE_LIMIT and
HAVE_MACH_VM_SET_SIZE_LIMIT.
* sysdeps/mach/configure.ac: use mach_RPC_CHECK to check for
vm_set_size_limit and vm_get_size_limit RPCs in gnumach.defs.
* sysdeps/mach/configure: regenerate file.
Use vm_get_size_limit to initialize RLIMIT_AS
* hurd/hurdrlimit.c(init_rlimit): use vm_get_size_limit to initialize
RLIMIT_AS entry of the _hurd_rlimits array.
Notify the kernel of the new VM size limits
* sysdeps/mach/hurd/setrlimit.c: use the vm_set_size_limit RPC,
if available, to notify the kernel of the new limits. Retry RPC
calls if they were interrupted by a signal.
Message-ID: <
03fb90a795b354a366ee73f56f73e6ad22a86cda.
1755220108.git.dnietoc@gmail.com>
/* Mach specific: define if the `thread_get_name' RPC is available. */
#undef HAVE_MACH_THREAD_GET_NAME
+/* Mach specific: define if the `vm_get_size_limit' RPC is available. */
+#undef HAVE_MACH_VM_GET_SIZE_LIMIT
+
+/* Mach specific: define if the `vm_set_size_limit' RPC is available. */
+#undef HAVE_MACH_VM_SET_SIZE_LIMIT
+
/* Mach/i386 specific: define if the `i386_io_perm_*' RPCs are available. */
#undef HAVE_I386_IO_PERM_MODIFY
__mutex_init (&_hurd_rlimit_lock);
+#ifdef HAVE_MACH_VM_GET_SIZE_LIMIT
+ __vm_get_size_limit (__mach_task_self (),
+ &_hurd_rlimits[RLIMIT_AS].rlim_cur, &_hurd_rlimits[RLIMIT_AS].rlim_max);
+#endif
+
for (i = 0; i < RLIM_NLIMITS; ++i)
{
if (_hurd_rlimits[i].rlim_max == 0)
fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for vm_set_size_limit in gnumach.defs" >&5
+printf %s "checking for vm_set_size_limit in gnumach.defs... " >&6; }
+if test ${libc_cv_mach_rpc_vm_set_size_limit+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <mach/gnumach.defs>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP_TRADITIONAL "vm_set_size_limit" >/dev/null 2>&1
+then :
+ libc_cv_mach_rpc_vm_set_size_limit=yes
+else case e in #(
+ e) libc_cv_mach_rpc_vm_set_size_limit=no ;;
+esac
+fi
+rm -rf conftest*
+ ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_rpc_vm_set_size_limit" >&5
+printf "%s\n" "$libc_cv_mach_rpc_vm_set_size_limit" >&6; }
+if test $libc_cv_mach_rpc_vm_set_size_limit = yes; then
+ printf "%s\n" "#define HAVE_MACH_VM_SET_SIZE_LIMIT 1" >>confdefs.h
+
+fi
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for vm_get_size_limit in gnumach.defs" >&5
+printf %s "checking for vm_get_size_limit in gnumach.defs... " >&6; }
+if test ${libc_cv_mach_rpc_vm_get_size_limit+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <mach/gnumach.defs>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP_TRADITIONAL "vm_get_size_limit" >/dev/null 2>&1
+then :
+ libc_cv_mach_rpc_vm_get_size_limit=yes
+else case e in #(
+ e) libc_cv_mach_rpc_vm_get_size_limit=no ;;
+esac
+fi
+rm -rf conftest*
+ ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mach_rpc_vm_get_size_limit" >&5
+printf "%s\n" "$libc_cv_mach_rpc_vm_get_size_limit" >&6; }
+if test $libc_cv_mach_rpc_vm_get_size_limit = yes; then
+ printf "%s\n" "#define HAVE_MACH_VM_GET_SIZE_LIMIT 1" >>confdefs.h
+
+fi
+
ac_fn_c_check_header_preproc "$LINENO" "mach/machine/ndr_def.h" "ac_cv_header_mach_machine_ndr_def_h"
if test "x$ac_cv_header_mach_machine_ndr_def_h" = xyes
HAVE_MACH_THREAD_SET_NAME)
mach_RPC_CHECK(gnumach.defs, thread_get_name,
HAVE_MACH_THREAD_GET_NAME)
+mach_RPC_CHECK(gnumach.defs, vm_set_size_limit,
+ HAVE_MACH_VM_SET_SIZE_LIMIT)
+mach_RPC_CHECK(gnumach.defs, vm_get_size_limit,
+ HAVE_MACH_VM_GET_SIZE_LIMIT)
AC_CHECK_HEADER(mach/machine/ndr_def.h, [dnl
DEFINES="$DEFINES -DNDR_DEF_HEADER='<mach/machine/ndr_def.h>'"], [dnl
__setrlimit (enum __rlimit_resource resource, const struct rlimit *rlimits)
{
struct rlimit lim;
+ error_t err = 0;
+ mach_port_t host = MACH_PORT_NULL;
if (rlimits == NULL || (unsigned int) resource >= RLIMIT_NLIMITS)
return __hurd_fail (EINVAL);
if (lim.rlim_cur > lim.rlim_max)
lim.rlim_cur = lim.rlim_max;
+retry:
HURD_CRITICAL_BEGIN;
__mutex_lock (&_hurd_rlimit_lock);
+
+#ifdef HAVE_MACH_VM_SET_SIZE_LIMIT
+ if (resource == RLIMIT_AS)
+ {
+ if (host == MACH_PORT_NULL)
+ {
+ /* Check whether the privileged host control port is required */
+ if (_hurd_rlimits[resource].rlim_max < lim.rlim_max)
+ {
+ err = __get_privileged_ports (&host, NULL);
+ if (err)
+ goto fail;
+ }
+ else
+ host = __mach_host_self ();
+ }
+
+ err = __vm_set_size_limit (host, __mach_task_self (),
+ lim.rlim_cur, lim.rlim_max);
+
+ if (err == MIG_BAD_ID)
+ /* MIG_BAD_ID returned as kernel support is missing, clear error */
+ err = 0;
+ else if (err)
+ {
+ if (err == KERN_NO_ACCESS)
+ err = EPERM;
+ goto fail;
+ }
+ }
+#endif
+
_hurd_rlimits[resource] = lim;
+
+#ifdef HAVE_MACH_VM_SET_SIZE_LIMIT
+fail:
+#endif
__mutex_unlock (&_hurd_rlimit_lock);
HURD_CRITICAL_END;
- return 0;
+ if (err == EINTR)
+ /* Got a signal while inside an RPC of the critical section, retry */
+ goto retry;
+
+ if (host != MACH_PORT_NULL && host != __mach_host_self ())
+ __mach_port_deallocate (__mach_task_self (), host);
+
+ return __hurd_fail (err);
}
libc_hidden_def (__setrlimit)