diff --git a/NEWS b/NEWS index 1d9ce09488..0b9a247241 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,12 @@ Major new features: and under Linux a spare has been allocated: it was always zero in previous versions of glibc, and zero is not a valid result. +* 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: [Add deprecations, removals and changes affecting compatibility here] 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 + . */ + +#ifndef _SPAWN_H +# error "Never include directly; use 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 + #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..a3aa020d5c --- /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 + . */ + +#ifndef _SPAWN_H +# error "Never include directly; use 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 *__restrict __cgroup) + __THROW __nonnull ((1, 2)); + +/* Sore the cgroupsv2 the attribute structure. */ +extern int posix_spawnattr_setcgroup_np (posix_spawnattr_t *__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 + . */ + +#include + +/* 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 + . */ + +#include + +/* 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..84e24696eb --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-spawn-cgroup.c @@ -0,0 +1,223 @@ +/* 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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: %m"); + + 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. */ +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); +} + +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 ("no 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 (expected %jx, got %jd)", + CGROUPFS, (intmax_t) fs.f_type, + (intmax_t) CGROUP2_SUPER_MAGIC); + + 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 || errno == EROFS) + 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]); + return 0; + } + + 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. */ + { + int r = do_test_cgroup_failure (NULL, -1); + if (r == EOPNOTSUPP) + FAIL_UNSUPPORTED ("posix_spawn POSIX_SPAWN_SETCGROUP is not supported"); + TEST_COMPARE (r, 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 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