Skip to content

Commit bca17d1

Browse files
kolyshkingopherbot
authored andcommitted
syscall: add CgroupFD support for ForkExec on Linux
Implement CLONE_INTO_CGROUP feature, allowing to put a child in a specified cgroup in a clean and simple way. Note that the feature only works for cgroup v2, and requires Linux kernel 5.7 or newer. Using the feature requires a new syscall, clone3. Currently this is the only reason to use clone3, but the code is structured in a way so that other cases may be easily added in the future. Add a test case. While at it, try to simplify the syscall calling code in forkAndExecInChild1, which became complicated over time because: 1. It was using either rawVforkSyscall or RawSyscall6 depending on whether CLONE_NEWUSER was set. 2. On Linux/s390, the first two arguments to clone(2) system call are swapped (which deserved a mention in Linux ABI hall of shame). It was worked around in rawVforkSyscall on s390, but had to be implemented via a switch/case when using RawSyscall6, making the code less clear. Let's - modify rawVforkSyscall to have two arguments (which is also required for clone3); - remove the arguments workaround from s390 asm, instead implementing arguments swap in the caller (which still looks ugly but at least it's done once and is clearly documented now); - use rawVforkSyscall for all cases (since it is essentially similar to RawSyscall6, except for having less parameters, not returning r2, and saving/restoring the return address before/after syscall on 386 and amd64). Updates #51246. Change-Id: Ifcd418ebead9257177338ffbcccd0bdecb94474e Reviewed-on: https://go-review.googlesource.com/c/go/+/417695 Auto-Submit: Ian Lance Taylor <[email protected]> Reviewed-by: Michael Knyszek <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> Run-TryBot: Kirill Kolyshkin <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent f53b211 commit bca17d1

24 files changed

+228
-99
lines changed

api/next/51246.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ pkg syscall (linux-386), const CLONE_NEWTIME = 128 #51246
88
pkg syscall (linux-386), const CLONE_NEWTIME ideal-int #51246
99
pkg syscall (linux-386), const CLONE_PIDFD = 4096 #51246
1010
pkg syscall (linux-386), const CLONE_PIDFD ideal-int #51246
11+
pkg syscall (linux-386), type SysProcAttr struct, CgroupFD int #51246
12+
pkg syscall (linux-386), type SysProcAttr struct, UseCgroupFD bool #51246
1113
pkg syscall (linux-386-cgo), const CLONE_CLEAR_SIGHAND = 4294967296 #51246
1214
pkg syscall (linux-386-cgo), const CLONE_CLEAR_SIGHAND ideal-int #51246
1315
pkg syscall (linux-386-cgo), const CLONE_INTO_CGROUP = 8589934592 #51246
@@ -18,6 +20,8 @@ pkg syscall (linux-386-cgo), const CLONE_NEWTIME = 128 #51246
1820
pkg syscall (linux-386-cgo), const CLONE_NEWTIME ideal-int #51246
1921
pkg syscall (linux-386-cgo), const CLONE_PIDFD = 4096 #51246
2022
pkg syscall (linux-386-cgo), const CLONE_PIDFD ideal-int #51246
23+
pkg syscall (linux-386-cgo), type SysProcAttr struct, CgroupFD int #51246
24+
pkg syscall (linux-386-cgo), type SysProcAttr struct, UseCgroupFD bool #51246
2125
pkg syscall (linux-amd64), const CLONE_CLEAR_SIGHAND = 4294967296 #51246
2226
pkg syscall (linux-amd64), const CLONE_CLEAR_SIGHAND ideal-int #51246
2327
pkg syscall (linux-amd64), const CLONE_INTO_CGROUP = 8589934592 #51246
@@ -28,6 +32,8 @@ pkg syscall (linux-amd64), const CLONE_NEWTIME = 128 #51246
2832
pkg syscall (linux-amd64), const CLONE_NEWTIME ideal-int #51246
2933
pkg syscall (linux-amd64), const CLONE_PIDFD = 4096 #51246
3034
pkg syscall (linux-amd64), const CLONE_PIDFD ideal-int #51246
35+
pkg syscall (linux-amd64), type SysProcAttr struct, CgroupFD int #51246
36+
pkg syscall (linux-amd64), type SysProcAttr struct, UseCgroupFD bool #51246
3137
pkg syscall (linux-amd64-cgo), const CLONE_CLEAR_SIGHAND = 4294967296 #51246
3238
pkg syscall (linux-amd64-cgo), const CLONE_CLEAR_SIGHAND ideal-int #51246
3339
pkg syscall (linux-amd64-cgo), const CLONE_INTO_CGROUP = 8589934592 #51246
@@ -38,6 +44,8 @@ pkg syscall (linux-amd64-cgo), const CLONE_NEWTIME = 128 #51246
3844
pkg syscall (linux-amd64-cgo), const CLONE_NEWTIME ideal-int #51246
3945
pkg syscall (linux-amd64-cgo), const CLONE_PIDFD = 4096 #51246
4046
pkg syscall (linux-amd64-cgo), const CLONE_PIDFD ideal-int #51246
47+
pkg syscall (linux-amd64-cgo), type SysProcAttr struct, CgroupFD int #51246
48+
pkg syscall (linux-amd64-cgo), type SysProcAttr struct, UseCgroupFD bool #51246
4149
pkg syscall (linux-arm), const CLONE_CLEAR_SIGHAND = 4294967296 #51246
4250
pkg syscall (linux-arm), const CLONE_CLEAR_SIGHAND ideal-int #51246
4351
pkg syscall (linux-arm), const CLONE_INTO_CGROUP = 8589934592 #51246
@@ -48,6 +56,8 @@ pkg syscall (linux-arm), const CLONE_NEWTIME = 128 #51246
4856
pkg syscall (linux-arm), const CLONE_NEWTIME ideal-int #51246
4957
pkg syscall (linux-arm), const CLONE_PIDFD = 4096 #51246
5058
pkg syscall (linux-arm), const CLONE_PIDFD ideal-int #51246
59+
pkg syscall (linux-arm), type SysProcAttr struct, CgroupFD int #51246
60+
pkg syscall (linux-arm), type SysProcAttr struct, UseCgroupFD bool #51246
5161
pkg syscall (linux-arm-cgo), const CLONE_CLEAR_SIGHAND = 4294967296 #51246
5262
pkg syscall (linux-arm-cgo), const CLONE_CLEAR_SIGHAND ideal-int #51246
5363
pkg syscall (linux-arm-cgo), const CLONE_INTO_CGROUP = 8589934592 #51246
@@ -58,3 +68,5 @@ pkg syscall (linux-arm-cgo), const CLONE_NEWTIME = 128 #51246
5868
pkg syscall (linux-arm-cgo), const CLONE_NEWTIME ideal-int #51246
5969
pkg syscall (linux-arm-cgo), const CLONE_PIDFD = 4096 #51246
6070
pkg syscall (linux-arm-cgo), const CLONE_PIDFD ideal-int #51246
71+
pkg syscall (linux-arm-cgo), type SysProcAttr struct, CgroupFD int #51246
72+
pkg syscall (linux-arm-cgo), type SysProcAttr struct, UseCgroupFD bool #51246

src/syscall/asm_linux_386.s

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,24 @@
1313
// instead of the glibc-specific "CALL 0x10(GS)".
1414
#define INVOKE_SYSCALL INT $0x80
1515

16-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
17-
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
16+
// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
17+
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-20
1818
MOVL trap+0(FP), AX // syscall entry
1919
MOVL a1+4(FP), BX
20-
MOVL $0, CX
20+
MOVL a2+8(FP), CX
2121
MOVL $0, DX
2222
POPL SI // preserve return address
2323
INVOKE_SYSCALL
2424
PUSHL SI
2525
CMPL AX, $0xfffff001
2626
JLS ok
27-
MOVL $-1, r1+8(FP)
27+
MOVL $-1, r1+12(FP)
2828
NEGL AX
29-
MOVL AX, err+12(FP)
29+
MOVL AX, err+16(FP)
3030
RET
3131
ok:
32-
MOVL AX, r1+8(FP)
33-
MOVL $0, err+12(FP)
32+
MOVL AX, r1+12(FP)
33+
MOVL $0, err+16(FP)
3434
RET
3535

3636
// func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);

src/syscall/asm_linux_amd64.s

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111

1212
#define SYS_gettimeofday 96
1313

14-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
15-
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
14+
// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
15+
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-40
1616
MOVQ a1+8(FP), DI
17-
MOVQ $0, SI
17+
MOVQ a2+16(FP), SI
1818
MOVQ $0, DX
1919
MOVQ $0, R10
2020
MOVQ $0, R8
@@ -25,13 +25,13 @@ TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
2525
PUSHQ R12
2626
CMPQ AX, $0xfffffffffffff001
2727
JLS ok2
28-
MOVQ $-1, r1+16(FP)
28+
MOVQ $-1, r1+24(FP)
2929
NEGQ AX
30-
MOVQ AX, err+24(FP)
30+
MOVQ AX, err+32(FP)
3131
RET
3232
ok2:
33-
MOVQ AX, r1+16(FP)
34-
MOVQ $0, err+24(FP)
33+
MOVQ AX, r1+24(FP)
34+
MOVQ $0, err+32(FP)
3535
RET
3636

3737
// func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)

src/syscall/asm_linux_arm.s

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,25 @@ okseek:
4141
BL runtime·exitsyscall(SB)
4242
RET
4343

44-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
45-
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
44+
// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
45+
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-20
4646
MOVW trap+0(FP), R7 // syscall entry
4747
MOVW a1+4(FP), R0
48-
MOVW $0, R1
48+
MOVW a2+8(FP), R1
4949
MOVW $0, R2
5050
SWI $0
5151
MOVW $0xfffff001, R1
5252
CMP R1, R0
5353
BLS ok
5454
MOVW $-1, R1
55-
MOVW R1, r1+8(FP)
55+
MOVW R1, r1+12(FP)
5656
RSB $0, R0, R0
57-
MOVW R0, err+12(FP)
57+
MOVW R0, err+16(FP)
5858
RET
5959
ok:
60-
MOVW R0, r1+8(FP)
60+
MOVW R0, r1+12(FP)
6161
MOVW $0, R0
62-
MOVW R0, err+12(FP)
62+
MOVW R0, err+16(FP)
6363
RET
6464

6565
// func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);

src/syscall/asm_linux_arm64.s

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
#include "textflag.h"
66

7-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
8-
TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-32
7+
// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
8+
TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-40
99
MOVD a1+8(FP), R0
10-
MOVD $0, R1
10+
MOVD a2+16(FP), R1
1111
MOVD $0, R2
1212
MOVD $0, R3
1313
MOVD $0, R4
@@ -17,13 +17,13 @@ TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-32
1717
CMN $4095, R0
1818
BCC ok
1919
MOVD $-1, R4
20-
MOVD R4, r1+16(FP) // r1
20+
MOVD R4, r1+24(FP) // r1
2121
NEG R0, R0
22-
MOVD R0, err+24(FP) // errno
22+
MOVD R0, err+32(FP) // errno
2323
RET
2424
ok:
25-
MOVD R0, r1+16(FP) // r1
26-
MOVD ZR, err+24(FP) // errno
25+
MOVD R0, r1+24(FP) // r1
26+
MOVD ZR, err+32(FP) // errno
2727
RET
2828

2929
// func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);

src/syscall/asm_linux_loong64.s

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
// System calls for loong64, Linux
99
//
1010

11-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
12-
TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-32
11+
// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
12+
TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-40
1313
MOVV a1+8(FP), R4
14-
MOVV $0, R5
14+
MOVV a2+16(FP), R5
1515
MOVV $0, R6
1616
MOVV $0, R7
1717
MOVV $0, R8
@@ -21,13 +21,13 @@ TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-32
2121
MOVW $-4096, R12
2222
BGEU R12, R4, ok
2323
MOVV $-1, R12
24-
MOVV R12, r1+16(FP) // r1
24+
MOVV R12, r1+24(FP) // r1
2525
SUBVU R4, R0, R4
26-
MOVV R4, err+24(FP) // errno
26+
MOVV R4, err+32(FP) // errno
2727
RET
2828
ok:
29-
MOVV R4, r1+16(FP) // r1
30-
MOVV R0, err+24(FP) // errno
29+
MOVV R4, r1+24(FP) // r1
30+
MOVV R0, err+32(FP) // errno
3131
RET
3232

3333
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48

src/syscall/asm_linux_mips64x.s

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
// System calls for mips64, Linux
1111
//
1212

13-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
14-
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
13+
// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
14+
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-40
1515
MOVV a1+8(FP), R4
16-
MOVV R0, R5
16+
MOVV a2+16(FP), R5
1717
MOVV R0, R6
1818
MOVV R0, R7
1919
MOVV R0, R8
@@ -22,12 +22,12 @@ TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
2222
SYSCALL
2323
BEQ R7, ok
2424
MOVV $-1, R1
25-
MOVV R1, r1+16(FP) // r1
26-
MOVV R2, err+24(FP) // errno
25+
MOVV R1, r1+24(FP) // r1
26+
MOVV R2, err+32(FP) // errno
2727
RET
2828
ok:
29-
MOVV R2, r1+16(FP) // r1
30-
MOVV R0, err+24(FP) // errno
29+
MOVV R2, r1+24(FP) // r1
30+
MOVV R0, err+32(FP) // errno
3131
RET
3232

3333
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48

src/syscall/asm_linux_mipsx.s

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,21 @@ ok9:
4444
JAL runtime·exitsyscall(SB)
4545
RET
4646

47-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
48-
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
47+
// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
48+
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-20
4949
MOVW a1+4(FP), R4
50-
MOVW R0, R5
50+
MOVW a2+8(FP), R5
5151
MOVW R0, R6
5252
MOVW trap+0(FP), R2 // syscall entry
5353
SYSCALL
5454
BEQ R7, ok
5555
MOVW $-1, R1
56-
MOVW R1, r1+8(FP) // r1
57-
MOVW R2, err+12(FP) // errno
56+
MOVW R1, r1+12(FP) // r1
57+
MOVW R2, err+16(FP) // errno
5858
RET
5959
ok:
60-
MOVW R2, r1+8(FP) // r1
61-
MOVW R0, err+12(FP) // errno
60+
MOVW R2, r1+12(FP) // r1
61+
MOVW R0, err+16(FP) // errno
6262
RET
6363

6464
TEXT ·rawSyscallNoError(SB),NOSPLIT,$20-24

src/syscall/asm_linux_ppc64x.s

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
// System calls for ppc64, Linux
1111
//
1212

13-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
14-
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
13+
// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
14+
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-40
1515
MOVD a1+8(FP), R3
16-
MOVD R0, R4
16+
MOVD a2+16(FP), R4
1717
MOVD R0, R5
1818
MOVD R0, R6
1919
MOVD R0, R7
@@ -22,12 +22,12 @@ TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
2222
SYSCALL R9
2323
BVC ok
2424
MOVD $-1, R4
25-
MOVD R4, r1+16(FP) // r1
26-
MOVD R3, err+24(FP) // errno
25+
MOVD R4, r1+24(FP) // r1
26+
MOVD R3, err+32(FP) // errno
2727
RET
2828
ok:
29-
MOVD R3, r1+16(FP) // r1
30-
MOVD R0, err+24(FP) // errno
29+
MOVD R3, r1+24(FP) // r1
30+
MOVD R0, err+32(FP) // errno
3131
RET
3232

3333
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48

src/syscall/asm_linux_riscv64.s

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
// System calls for riscv64, Linux
99
//
1010

11-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
12-
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
11+
// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
12+
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-40
1313
MOV a1+8(FP), A0
14-
MOV ZERO, A1
14+
MOV a2+16(FP), A1
1515
MOV ZERO, A2
1616
MOV ZERO, A3
1717
MOV ZERO, A4
@@ -20,14 +20,14 @@ TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
2020
ECALL
2121
MOV $-4096, T0
2222
BLTU T0, A0, err
23-
MOV A0, r1+16(FP) // r1
24-
MOV ZERO, err+24(FP) // errno
23+
MOV A0, r1+24(FP) // r1
24+
MOV ZERO, err+32(FP) // errno
2525
RET
2626
err:
2727
MOV $-1, T0
28-
MOV T0, r1+16(FP) // r1
28+
MOV T0, r1+24(FP) // r1
2929
SUB A0, ZERO, A0
30-
MOV A0, err+24(FP) // errno
30+
MOV A0, err+32(FP) // errno
3131
RET
3232

3333
TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48

src/syscall/asm_linux_s390x.s

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
// System calls for s390x, Linux
99
//
1010

11-
// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
12-
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
13-
MOVD $0, R2
14-
MOVD a1+8(FP), R3
11+
// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
12+
TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-40
13+
MOVD a1+8(FP), R2
14+
MOVD a2+16(FP), R3
1515
MOVD $0, R4
1616
MOVD $0, R5
1717
MOVD $0, R6
@@ -20,13 +20,13 @@ TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
2020
SYSCALL
2121
MOVD $0xfffffffffffff001, R8
2222
CMPUBLT R2, R8, ok2
23-
MOVD $-1, r1+16(FP)
23+
MOVD $-1, r1+24(FP)
2424
NEG R2, R2
25-
MOVD R2, err+24(FP) // errno
25+
MOVD R2, err+32(FP) // errno
2626
RET
2727
ok2:
28-
MOVD R2, r1+16(FP)
29-
MOVD $0, err+24(FP) // errno
28+
MOVD R2, r1+24(FP)
29+
MOVD $0, err+32(FP) // errno
3030
RET
3131

3232
// func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)

0 commit comments

Comments
 (0)