@@ -54,6 +54,12 @@ Major new features:
explicitly enabled, then fortify source is forcibly disabled so to keep
original behavior unchanged.
+* On Linux, the functions posix_spawnattr_getcgroup_np and
+ posix_spawnattr_setcgroup_np have been added, along with the
+ POSIX_SPAWN_SETCGROUP flag. They allow posix_spawn and posix_spawnp to
+ set the cgroupv2 in the new process in a race free manner. These functions
+ are GNU extensions and require a kernel with clone3 support.
+
Deprecated and removed features, and other changes affecting compatibility:
* In the Linux kernel for the hppa/parisc architecture some of the
new file mode 100644
@@ -0,0 +1,21 @@
+/* POSIX spawn extensions. Generic version.
+ Copyright (C) 2023 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 _SPAWN_H
+# error "Never include <bits/spawn-ext.h> directly; use <spawn.h> instead."
+#endif
@@ -37,6 +37,7 @@ headers := \
bits/pthreadtypes-arch.h \
bits/pthreadtypes.h \
bits/sched.h \
+ bits/spawn_ext.h \
bits/thread-shared-types.h \
bits/types.h \
bits/types/idtype_t.h \
@@ -34,7 +34,8 @@ typedef struct
sigset_t __ss;
struct sched_param __sp;
int __policy;
- int __pad[16];
+ int __cgroup;
+ int __pad[15];
} posix_spawnattr_t;
@@ -59,6 +60,7 @@ typedef struct
#ifdef __USE_GNU
# define POSIX_SPAWN_USEVFORK 0x40
# define POSIX_SPAWN_SETSID 0x80
+# define POSIX_SPAWN_SETCGROUP 0x100
#endif
@@ -231,4 +233,6 @@ posix_spawn_file_actions_addtcsetpgrp_np (posix_spawn_file_actions_t *,
__END_DECLS
+#include <bits/spawn_ext.h>
+
#endif /* spawn.h */
@@ -26,7 +26,8 @@
| POSIX_SPAWN_SETSCHEDPARAM \
| POSIX_SPAWN_SETSCHEDULER \
| POSIX_SPAWN_SETSID \
- | POSIX_SPAWN_USEVFORK)
+ | POSIX_SPAWN_USEVFORK \
+ | POSIX_SPAWN_SETCGROUP)
/* Store flags in the attribute structure. */
int
@@ -493,11 +493,14 @@ sysdep_routines += \
getcpu \
oldglob \
sched_getcpu \
+ spawnattr_getcgroup_np \
+ spawnattr_setcgroup_np \
# sysdep_routines
tests += \
tst-affinity \
tst-affinity-pid \
+ tst-spawn-cgroup \
# tests
tests-static += \
@@ -511,6 +514,8 @@ tests += \
CFLAGS-fork.c = $(libio-mtsafe)
CFLAGS-getpid.o = -fomit-frame-pointer
CFLAGS-getpid.os = -fomit-frame-pointer
+
+tst-spawn-cgroup-ARGS = -- $(host-test-program-cmd)
endif
ifeq ($(subdir),inet)
@@ -321,6 +321,10 @@ libc {
__ppoll64_chk;
%endif
}
+ GLIBC_2.38 {
+ posix_spawnattr_getcgroup_np;
+ posix_spawnattr_setcgroup_np;
+ }
GLIBC_PRIVATE {
# functions used in other libraries
__syscall_rt_sigqueueinfo;
@@ -2669,6 +2669,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2778,6 +2778,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2430,6 +2430,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -550,6 +550,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -547,6 +547,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
new file mode 100644
@@ -0,0 +1,40 @@
+/* POSIX spawn extensions. Linux version.
+ Copyright (C) 2023 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 _SPAWN_H
+# error "Never include <bits/spawn-ext.h> directly; use <spawn.h> instead."
+#endif
+
+__BEGIN_DECLS
+
+#ifdef __USE_MISC
+
+/* Get the cgroupsv2 the attribute structure. */
+extern int posix_spawnattr_getcgroup_np (const posix_spawnattr_t *
+ __restrict __attr,
+ int *__cgroup)
+ __THROW __nonnull ((1, 2));
+
+/* Store scheduling parameters in the attribute structure. */
+extern int posix_spawnattr_setcgroup_np (posix_spawnattr_t *__restrict __attr,
+ int __cgroup)
+ __THROW __nonnull ((1));
+
+#endif /* __USE_MISC */
+
+__END_DECLS
@@ -2706,6 +2706,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2655,6 +2655,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2839,6 +2839,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2604,6 +2604,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2190,6 +2190,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -551,6 +551,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2782,6 +2782,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2755,6 +2755,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2752,6 +2752,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2747,6 +2747,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2745,6 +2745,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2753,6 +2753,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2655,6 +2655,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2794,6 +2794,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2176,6 +2176,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2821,6 +2821,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2854,6 +2854,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2575,6 +2575,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2889,6 +2889,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2432,6 +2432,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2632,6 +2632,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2819,6 +2819,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2612,6 +2612,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2662,6 +2662,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2659,6 +2659,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2814,6 +2814,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2627,6 +2627,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
new file mode 100644
@@ -0,0 +1,28 @@
+/* Copyright (C) 2000-2023 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/>. */
+
+#include <spawn.h>
+
+/* Get scheduling policy from the attribute structure. */
+int
+posix_spawnattr_getcgroup_np (const posix_spawnattr_t *attr,
+ int *cgroup)
+{
+ *cgroup = attr->__cgroup;
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,27 @@
+/* Copyright (C) 2000-2023 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/>. */
+
+#include <spawn.h>
+
+/* Store scheduling policy in the attribute structure. */
+int
+posix_spawnattr_setcgroup_np (posix_spawnattr_t *attr, int cgroup)
+{
+ attr->__cgroup = cgroup;
+
+ return 0;
+}
@@ -380,14 +380,19 @@ __spawnix (pid_t * pid, const char *file,
need for CLONE_SETTLS. Although parent and child share the same TLS
namespace, there will be no concurrent access for TLS variables (errno
for instance). */
+ bool set_cgroup = attrp ? (attrp->__flags & POSIX_SPAWN_SETCGROUP) : false;
struct clone_args clone_args =
{
/* Unsupported flags like CLONE_CLEAR_SIGHAND will be cleared up by
__clone_internal_fallback. */
- .flags = CLONE_CLEAR_SIGHAND | CLONE_VM | CLONE_VFORK,
+ .flags = (set_cgroup ? CLONE_INTO_CGROUP : 0)
+ | CLONE_CLEAR_SIGHAND
+ | CLONE_VM
+ | CLONE_VFORK,
.exit_signal = SIGCHLD,
.stack = (uintptr_t) stack,
.stack_size = stack_size,
+ .cgroup = (set_cgroup ? attrp->__cgroup : 0)
};
#ifdef HAVE_CLONE3_WRAPPER
args.use_clone3 = true;
@@ -398,8 +403,17 @@ __spawnix (pid_t * pid, const char *file,
#endif
{
args.use_clone3 = false;
- new_pid = __clone_internal_fallback (&clone_args, __spawni_child,
- &args);
+ if (!set_cgroup)
+ new_pid = __clone_internal_fallback (&clone_args, __spawni_child,
+ &args);
+ else
+ {
+ /* No fallback for POSIX_SPAWN_SETCGROUP if clone3 is not
+ supported. */
+ new_pid = -1;
+ if (errno == ENOSYS)
+ errno = ENOTSUP;
+ }
}
/* It needs to collect the case where the auxiliary process was created
new file mode 100644
@@ -0,0 +1,216 @@
+/* Tests for posix_spawn cgroup extension.
+ Copyright (C) 2023 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <spawn.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <support/temp_file.h>
+#include <sys/vfs.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#define CGROUPFS "/sys/fs/cgroup/"
+#ifndef CGROUP2_SUPER_MAGIC
+# define CGROUP2_SUPER_MAGIC 0x63677270
+#endif
+
+#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
+
+#define CGROUP_TEST "test-spawn-cgroup"
+
+/* Nonzero if the program gets called via `exec'. */
+#define CMDLINE_OPTIONS \
+ { "restart", no_argument, &restart, 1 },
+static int restart;
+
+/* Hold the four initial argument used to respawn the process, plus the extra
+ '--direct', '--restart', the check type ('SIG_IGN' or 'SIG_DFL'), and a
+ final NULL. */
+static char *spargs[8];
+
+static inline char *
+startswith (const char *s, const char *prefix)
+{
+ size_t l = strlen (prefix);
+ if (strncmp (s, prefix, l) == 0)
+ return (char *) s + l;
+ return NULL;
+}
+
+static char *
+get_cgroup (void)
+{
+ FILE *f = fopen ("/proc/self/cgroup", "re");
+ if (f == NULL)
+ FAIL_UNSUPPORTED ("no cgroup defined for the process");
+
+ char *cgroup = NULL;
+
+ char *line = NULL;
+ size_t linesiz = 0;
+ while (xgetline (&line, &linesiz, f) > 0)
+ {
+ char *entry = startswith (line, "0:");
+ if (entry == NULL)
+ continue;
+
+ entry = strchr (entry, ':');
+ if (entry == NULL)
+ continue;
+
+ cgroup = entry + 1;
+ size_t l = strlen (cgroup);
+ if (cgroup[l - 1] == '\n')
+ cgroup[l - 1] = '\0';
+
+ cgroup = xstrdup (entry + 1);
+ break;
+ }
+
+ xfclose (f);
+ free (line);
+
+ return cgroup;
+}
+
+
+/* Called on process re-execution. */
+_Noreturn static void
+handle_restart (int argc, char *argv[])
+{
+ assert (argc == 1);
+ char *newcgroup = argv[0];
+
+ char *current_cgroup = get_cgroup ();
+ TEST_VERIFY_EXIT (current_cgroup != NULL);
+ TEST_COMPARE_STRING (newcgroup, current_cgroup);
+ exit (EXIT_SUCCESS);
+}
+
+static int
+do_test_cgroup_failure (pid_t *pid, int cgroup)
+{
+ posix_spawnattr_t attr;
+ TEST_COMPARE (posix_spawnattr_init (&attr), 0);
+ TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETCGROUP), 0);
+ TEST_COMPARE (posix_spawnattr_setcgroup_np (&attr, cgroup), 0);
+
+ int cgetgroup;
+ TEST_COMPARE (posix_spawnattr_getcgroup_np (&attr, &cgetgroup), 0);
+ TEST_COMPARE (cgroup, cgetgroup);
+
+ return posix_spawn (pid, spargs[0], NULL, &attr, spargs, environ);
+}
+
+static int
+create_new_cgroup (char **newcgroup)
+{
+ struct statfs fs;
+ if (statfs (CGROUPFS, &fs) < 0)
+ {
+ if (errno == ENOENT)
+ FAIL_UNSUPPORTED ("not cgroupv2 mount found");
+ FAIL_EXIT1 ("statfs (%s): %m\n", CGROUPFS);
+ }
+
+ if (!F_TYPE_EQUAL (fs.f_type, CGROUP2_SUPER_MAGIC))
+ FAIL_UNSUPPORTED ("%s is not a cgroupv2", CGROUPFS);
+
+ char *cgroup = get_cgroup ();
+ TEST_VERIFY_EXIT (cgroup != NULL);
+ *newcgroup = xasprintf ("%s/%s", cgroup, CGROUP_TEST);
+ char *cgpath = xasprintf ("%s%s/%s", CGROUPFS, cgroup, CGROUP_TEST);
+ free (cgroup);
+
+ if (mkdir (cgpath, 0755) == -1 && errno != EEXIST)
+ {
+ if (errno == EACCES || errno == EPERM)
+ FAIL_UNSUPPORTED ("can not create a new cgroupv2 group");
+ FAIL_EXIT1 ("mkdir (%s): %m", cgpath);
+ }
+ add_temp_file (cgpath);
+
+ return xopen (cgpath, O_DIRECTORY | O_RDONLY | O_CLOEXEC, 0666);
+}
+
+static int
+do_test (int argc, char *argv[])
+{
+ /* We must have either:
+
+ - one or four parameters if called initially:
+ + argv[1]: path for ld.so optional
+ + argv[2]: "--library-path" optional
+ + argv[3]: the library path optional
+ + argv[4]: the application name
+
+ - six parameters left if called through re-execution:
+ + argv[4/1]: the application name
+ + argv[5/2]: the created cgroup
+
+ * When built with --enable-hardcoded-path-in-tests or issued without
+ using the loader directly. */
+
+ if (restart)
+ handle_restart (argc - 1, &argv[1]);
+
+ TEST_VERIFY_EXIT (argc == 2 || argc == 5);
+
+ char *newcgroup;
+ int cgroup = create_new_cgroup (&newcgroup);
+
+ int i;
+ for (i = 0; i < argc - 1; i++)
+ spargs[i] = argv[i + 1];
+ spargs[i++] = (char *) "--direct";
+ spargs[i++] = (char *) "--restart";
+ spargs[i++] = (char *) newcgroup;
+ spargs[i] = NULL;
+
+ /* Check if invalid cgroups returns an error. */
+ {
+ TEST_COMPARE (do_test_cgroup_failure (NULL, -1), EINVAL);
+ }
+
+ {
+ pid_t pid;
+ TEST_COMPARE (do_test_cgroup_failure (&pid, cgroup), 0);
+
+ siginfo_t sinfo;
+ TEST_COMPARE (waitid (P_PID, pid, &sinfo, WEXITED), 0);
+ TEST_COMPARE (sinfo.si_signo, SIGCHLD);
+ TEST_COMPARE (sinfo.si_code, CLD_EXITED);
+ TEST_COMPARE (sinfo.si_status, 0);
+ }
+
+ xclose (cgroup);
+ free (newcgroup);
+
+ return 0;
+}
+
+#define TEST_FUNCTION_ARGV do_test
+#include <support/test-driver.c>
@@ -2578,6 +2578,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F
@@ -2684,6 +2684,8 @@ GLIBC_2.38 __strlcat_chk F
GLIBC_2.38 __strlcpy_chk F
GLIBC_2.38 __wcslcat_chk F
GLIBC_2.38 __wcslcpy_chk F
+GLIBC_2.38 posix_spawnattr_getcgroup_np F
+GLIBC_2.38 posix_spawnattr_setcgroup_np F
GLIBC_2.38 strlcat F
GLIBC_2.38 strlcpy F
GLIBC_2.38 wcslcat F