[PATCH v7 4/8] linux: Add posix_spawnattr_{get, set}cgroup_np (BZ 26731)
Carlos O'Donell
carlos@redhat.com
Mon Aug 14 13:27:10 GMT 2023
On 8/3/23 12:35, Adhemerval Zanella via Libc-alpha wrote:
> These function allow to posix_spawn and posix_spawnp to use
> CLONE_INTO_CGROUP with clone3, allowing the child process to
> be created in a different version 2 cgroup. These are GNU
> extensions that are available only for Linux, and also only
> for the architectures that implement clone3 wrapper
> (HAVE_CLONE3_WRAPPER).
This fails pre-commit CI for AArch64
https://patchwork.sourceware.org/project/glibc/patch/20230803163558.991832-5-adhemerval.zanella@linaro.org/
Please review the result.
> To create a process on a different cgroupv2, one can use the:
>
> posix_spawnattr_t attr;
> posix_spawnattr_init (&attr);
> posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETCGROUP);
> posix_spawnattr_setcgroup_np (&attr, cgroup);
> posix_spawn (...)
>
> Similar to other posix_spawn flags, POSIX_SPAWN_SETCGROUP control
> whether the cgroup file descriptor will be used or not with
> clone3.
>
> There is no fallback is either clone3 does not support the flag
> or if the architecture does not provide the clone3 wrapper, in
> this case posix_spawn returns ENOTSUP.
>
> Checked on x86_64-linux-gnu.
> ---
> NEWS | 6 +-
> bits/spawn_ext.h | 21 ++
> posix/Makefile | 1 +
> posix/spawn.h | 6 +-
> posix/spawnattr_setflags.c | 3 +-
> sysdeps/unix/sysv/linux/Makefile | 5 +
> sysdeps/unix/sysv/linux/Versions | 4 +
> sysdeps/unix/sysv/linux/aarch64/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/alpha/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/arc/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/arm/be/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/arm/le/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/bits/spawn_ext.h | 40 ++++
> sysdeps/unix/sysv/linux/csky/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/hppa/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/i386/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/ia64/libc.abilist | 2 +
> .../sysv/linux/loongarch/lp64/libc.abilist | 2 +
> .../sysv/linux/m68k/coldfire/libc.abilist | 2 +
> .../unix/sysv/linux/m68k/m680x0/libc.abilist | 2 +
> .../sysv/linux/microblaze/be/libc.abilist | 2 +
> .../sysv/linux/microblaze/le/libc.abilist | 2 +
> .../sysv/linux/mips/mips32/fpu/libc.abilist | 2 +
> .../sysv/linux/mips/mips32/nofpu/libc.abilist | 2 +
> .../sysv/linux/mips/mips64/n32/libc.abilist | 2 +
> .../sysv/linux/mips/mips64/n64/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/nios2/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/or1k/libc.abilist | 2 +
> .../linux/powerpc/powerpc32/fpu/libc.abilist | 2 +
> .../powerpc/powerpc32/nofpu/libc.abilist | 2 +
> .../linux/powerpc/powerpc64/be/libc.abilist | 2 +
> .../linux/powerpc/powerpc64/le/libc.abilist | 2 +
> .../unix/sysv/linux/riscv/rv32/libc.abilist | 2 +
> .../unix/sysv/linux/riscv/rv64/libc.abilist | 2 +
> .../unix/sysv/linux/s390/s390-32/libc.abilist | 2 +
> .../unix/sysv/linux/s390/s390-64/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/sh/be/libc.abilist | 2 +
> sysdeps/unix/sysv/linux/sh/le/libc.abilist | 2 +
> .../sysv/linux/sparc/sparc32/libc.abilist | 2 +
> .../sysv/linux/sparc/sparc64/libc.abilist | 2 +
> .../unix/sysv/linux/spawnattr_getcgroup_np.c | 28 +++
> .../unix/sysv/linux/spawnattr_setcgroup_np.c | 27 +++
> sysdeps/unix/sysv/linux/spawni.c | 22 +-
> sysdeps/unix/sysv/linux/tst-spawn-cgroup.c | 216 ++++++++++++++++++
> .../unix/sysv/linux/x86_64/64/libc.abilist | 2 +
> .../unix/sysv/linux/x86_64/x32/libc.abilist | 2 +
> 46 files changed, 441 insertions(+), 6 deletions(-)
> create mode 100644 bits/spawn_ext.h
> create mode 100644 sysdeps/unix/sysv/linux/bits/spawn_ext.h
> create mode 100644 sysdeps/unix/sysv/linux/spawnattr_getcgroup_np.c
> create mode 100644 sysdeps/unix/sysv/linux/spawnattr_setcgroup_np.c
> create mode 100644 sysdeps/unix/sysv/linux/tst-spawn-cgroup.c
>
> diff --git a/NEWS b/NEWS
> index 22875d5fa4..99824eab95 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -9,7 +9,11 @@ Version 2.39
>
> Major new features:
>
> - [Add new features here]
> +* 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:
>
> diff --git a/bits/spawn_ext.h b/bits/spawn_ext.h
> new file mode 100644
> index 0000000000..75b504a768
> --- /dev/null
> +++ b/bits/spawn_ext.h
> @@ -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
> diff --git a/posix/Makefile b/posix/Makefile
> index 3d368b91f6..70faad4b63 100644
> --- a/posix/Makefile
> +++ b/posix/Makefile
> @@ -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 \
> diff --git a/posix/spawn.h b/posix/spawn.h
> index 04cc525fa5..731862cc5a 100644
> --- a/posix/spawn.h
> +++ b/posix/spawn.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 */
> diff --git a/posix/spawnattr_setflags.c b/posix/spawnattr_setflags.c
> index 97153948e4..e7bb217c6a 100644
> --- a/posix/spawnattr_setflags.c
> +++ b/posix/spawnattr_setflags.c
> @@ -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
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index be801e3be4..d7b020154a 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -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)
> diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
> index bc59bce42f..6d8a67039e 100644
> --- a/sysdeps/unix/sysv/linux/Versions
> +++ b/sysdeps/unix/sysv/linux/Versions
> @@ -321,6 +321,10 @@ libc {
> __ppoll64_chk;
> %endif
> }
> + GLIBC_2.39 {
> + posix_spawnattr_getcgroup_np;
> + posix_spawnattr_setcgroup_np;
> + }
> GLIBC_PRIVATE {
> # functions used in other libraries
> __syscall_rt_sigqueueinfo;
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> index c49363e70e..0090827e01 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> @@ -2673,3 +2673,5 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> index d6b1dcaae6..9d099471b6 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> @@ -2782,6 +2782,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 _IO_fprintf F
> GLIBC_2.4 _IO_printf F
> GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
> index dfe0c3f7b6..d7ed2f66de 100644
> --- a/sysdeps/unix/sysv/linux/arc/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
> @@ -2434,3 +2434,5 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> index 6c75e5aa76..92e686defe 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> @@ -554,6 +554,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 _Exit F
> GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
> GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
> diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> index 03d6f7ae2d..b503e642fc 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> @@ -551,6 +551,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 _Exit F
> GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
> GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
> diff --git a/sysdeps/unix/sysv/linux/bits/spawn_ext.h b/sysdeps/unix/sysv/linux/bits/spawn_ext.h
> new file mode 100644
> index 0000000000..3bc10ab477
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/bits/spawn_ext.h
> @@ -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
> diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
> index d858c108c6..ec9e209b8d 100644
> --- a/sysdeps/unix/sysv/linux/csky/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
> @@ -2710,3 +2710,5 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> index 82a14f8ace..961f88bf14 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> @@ -2659,6 +2659,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 __confstr_chk F
> GLIBC_2.4 __fgets_chk F
> GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> index 1950b15d5d..b6f5a4ab83 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> @@ -2843,6 +2843,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 __confstr_chk F
> GLIBC_2.4 __fgets_chk F
> GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> index d0b9cb279b..a404b99e68 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> @@ -2608,6 +2608,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 __confstr_chk F
> GLIBC_2.4 __fgets_chk F
> GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
> index e760a631dd..2f9f6e2332 100644
> --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
> @@ -2194,3 +2194,5 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> index 35785a3d5f..b7e9ab4558 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> @@ -555,6 +555,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 _Exit F
> GLIBC_2.4 _IO_2_1_stderr_ D 0x98
> GLIBC_2.4 _IO_2_1_stdin_ D 0x98
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> index 4ab2426e0a..c345da7e0a 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> @@ -2786,6 +2786,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 __confstr_chk F
> GLIBC_2.4 __fgets_chk F
> GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> index 38faa16232..a643d868a8 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> @@ -2759,3 +2759,5 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> index 374d658988..fed535742c 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> @@ -2756,3 +2756,5 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> index fcc5e88e91..147bac3eaf 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> @@ -2751,6 +2751,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 __confstr_chk F
> GLIBC_2.4 __fgets_chk F
> GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> index 01eb96cd93..e550616576 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> @@ -2749,6 +2749,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 __confstr_chk F
> GLIBC_2.4 __fgets_chk F
> GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> index a2748b7b74..56f414dbd0 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> @@ -2757,6 +2757,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 __confstr_chk F
> GLIBC_2.4 __fgets_chk F
> GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> index 0ae7ba499d..da704a2e2b 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> @@ -2659,6 +2659,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 __confstr_chk F
> GLIBC_2.4 __fgets_chk F
> GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> index 947495a0e2..f5a157ea94 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> @@ -2798,3 +2798,5 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> index 115f1039e7..85b552f1cb 100644
> --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> @@ -2180,3 +2180,5 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> index 19c4c325b0..cadb16c12f 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> @@ -2825,6 +2825,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 _IO_fprintf F
> GLIBC_2.4 _IO_printf F
> GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> index 3e043c4044..50c5b99728 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> @@ -2858,6 +2858,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 _IO_fprintf F
> GLIBC_2.4 _IO_printf F
> GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> index e4f3a766bb..81c63385af 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> @@ -2579,6 +2579,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 _IO_fprintf F
> GLIBC_2.4 _IO_printf F
> GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> index dafe1c4a59..af9be18108 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> @@ -2893,3 +2893,5 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> index b9740a1afc..2266a88ad5 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> @@ -2436,3 +2436,5 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> index e3b4656aa2..4776ae32b8 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> @@ -2636,3 +2636,5 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> index 84cb7a50ed..5d1d7d07a5 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> @@ -2823,6 +2823,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 _IO_fprintf F
> GLIBC_2.4 _IO_printf F
> GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> index 33df3b1646..fffc32a0f4 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> @@ -2616,6 +2616,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 _IO_fprintf F
> GLIBC_2.4 _IO_printf F
> GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> index 94cbccd715..43ff21447d 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> @@ -2666,6 +2666,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 __confstr_chk F
> GLIBC_2.4 __fgets_chk F
> GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> index 3bb316a787..9ea18d5886 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> @@ -2663,6 +2663,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 __confstr_chk F
> GLIBC_2.4 __fgets_chk F
> GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index 6341b491b4..c6607d5385 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -2818,6 +2818,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 _IO_fprintf F
> GLIBC_2.4 _IO_printf F
> GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> index 8ed1ea2926..a010a2bb16 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> @@ -2631,6 +2631,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 __confstr_chk F
> GLIBC_2.4 __fgets_chk F
> GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/spawnattr_getcgroup_np.c b/sysdeps/unix/sysv/linux/spawnattr_getcgroup_np.c
> new file mode 100644
> index 0000000000..82fd8f4b71
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/spawnattr_getcgroup_np.c
> @@ -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;
> +}
> diff --git a/sysdeps/unix/sysv/linux/spawnattr_setcgroup_np.c b/sysdeps/unix/sysv/linux/spawnattr_setcgroup_np.c
> new file mode 100644
> index 0000000000..74d60bb5ea
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/spawnattr_setcgroup_np.c
> @@ -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;
> +}
> diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c
> index ec687cb423..f0d4c62ae6 100644
> --- a/sysdeps/unix/sysv/linux/spawni.c
> +++ b/sysdeps/unix/sysv/linux/spawni.c
> @@ -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,19 @@ __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;
> +#ifdef HAVE_CLONE3_WRAPPER
> + if (errno == ENOSYS)
> +#endif
> + errno = ENOTSUP;
> + }
> }
>
> /* It needs to collect the case where the auxiliary process was created
> diff --git a/sysdeps/unix/sysv/linux/tst-spawn-cgroup.c b/sysdeps/unix/sysv/linux/tst-spawn-cgroup.c
> new file mode 100644
> index 0000000000..6dba30ab29
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-spawn-cgroup.c
> @@ -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>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index 57cfcc2086..3591b5de5e 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -2582,6 +2582,8 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
> GLIBC_2.4 __confstr_chk F
> GLIBC_2.4 __fgets_chk F
> GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> index 3f0a9f6d82..ffbd8f3738 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> @@ -2688,3 +2688,5 @@ GLIBC_2.38 strlcat F
> GLIBC_2.38 strlcpy F
> GLIBC_2.38 wcslcat F
> GLIBC_2.38 wcslcpy F
> +GLIBC_2.39 posix_spawnattr_getcgroup_np F
> +GLIBC_2.39 posix_spawnattr_setcgroup_np F
--
Cheers,
Carlos.
More information about the Libc-alpha
mailing list