-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add syscall testing with sched tests
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
- Loading branch information
1 parent
bc0b9d2
commit c0b3fbc
Showing
6 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#syntax=docker/dockerfile:1.3-labs | ||
|
||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.1.0 AS xx | ||
|
||
FROM scratch AS src | ||
COPY *.go go.* / | ||
|
||
FROM --platform=$BUILDPLATFORM golang:1.17-alpine AS build | ||
COPY --from=xx / / | ||
RUN apk add clang lld file | ||
ARG TARGETPLATFORM | ||
RUN xx-apk add musl-dev linux-headers gcc | ||
WORKDIR /src | ||
RUN XX_CC_PREFER_STATIC_LINKER=1 xx-clang --setup-target-triple | ||
RUN --mount=from=src \ | ||
--mount=type=cache,target=/root/.cache/go-build \ | ||
--mount=type=cache,target=/go/pkg \ | ||
CGO_ENABLED=1 xx-go test -c -o /out/test -ldflags "-linkmode external -extldflags -static" . && \ | ||
xx-verify --static /out/test | ||
|
||
FROM scratch AS binary | ||
COPY --from=build /out/test . | ||
|
||
FROM alpine AS run | ||
RUN apk add libcap | ||
COPY --from=binary / /usr/bin | ||
ARG CONFIG_RT_GROUP_SCHED | ||
RUN --security=insecure /usr/bin/test -test.v | ||
|
||
FROM binary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
module github.com/tonistiigi/binfmt/test | ||
|
||
go 1.17 | ||
|
||
require ( | ||
github.com/stretchr/testify v1.7.0 | ||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 | ||
) | ||
|
||
require ( | ||
github.com/davecgh/go-spew v1.1.0 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= | ||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 h1:TyHqChC80pFkXWraUUf6RuB5IqFdQieMLwwCJokV2pc= | ||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package tests | ||
|
||
import ( | ||
"syscall" | ||
"unsafe" | ||
|
||
"golang.org/x/sys/unix" | ||
) | ||
|
||
// #include <linux/sched.h> | ||
// #include <linux/sched/types.h> | ||
// typedef struct sched_param sched_param; | ||
import "C" | ||
|
||
type Policy uint32 | ||
|
||
const ( | ||
SCHED_NORMAL Policy = C.SCHED_NORMAL | ||
SCHED_FIFO Policy = C.SCHED_FIFO | ||
SCHED_RR Policy = C.SCHED_RR | ||
SCHED_BATCH Policy = C.SCHED_BATCH | ||
SCHED_IDLE Policy = C.SCHED_IDLE | ||
SCHED_DEADLINE Policy = C.SCHED_DEADLINE | ||
) | ||
|
||
type SchedFlag int | ||
|
||
const ( | ||
SCHED_FLAG_RESET_ON_FORK SchedFlag = C.SCHED_FLAG_RESET_ON_FORK | ||
SCHED_FLAG_RECLAIM SchedFlag = C.SCHED_FLAG_RECLAIM | ||
SCHED_FLAG_DL_OVERRUN SchedFlag = C.SCHED_FLAG_DL_OVERRUN | ||
) | ||
|
||
type SchedParam C.sched_param | ||
|
||
func SchedGetScheduler(pid int) (Policy, error) { | ||
r0, _, e1 := unix.Syscall(unix.SYS_SCHED_GETSCHEDULER, uintptr(pid), 0, 0) | ||
if e1 != 0 { | ||
return 0, syscall.Errno(e1) | ||
} | ||
return Policy(r0), nil | ||
} | ||
|
||
func SchedSetScheduler(pid int, p Policy, param SchedParam) error { | ||
_, _, e1 := unix.Syscall(unix.SYS_SCHED_SETSCHEDULER, uintptr(pid), uintptr(p), uintptr(unsafe.Pointer(¶m))) | ||
if e1 != 0 { | ||
return syscall.Errno(e1) | ||
} | ||
return nil | ||
} | ||
|
||
func SchedGetPriorityMin(p Policy) (int, error) { | ||
r0, _, e1 := unix.Syscall(unix.SYS_SCHED_GET_PRIORITY_MIN, uintptr(p), 0, 0) | ||
if e1 != 0 { | ||
return 0, syscall.Errno(e1) | ||
} | ||
return int(r0), nil | ||
} | ||
|
||
func SchedGetPriorityMax(p Policy) (int, error) { | ||
r0, _, e1 := unix.Syscall(unix.SYS_SCHED_GET_PRIORITY_MAX, uintptr(p), 0, 0) | ||
if e1 != 0 { | ||
return 0, syscall.Errno(e1) | ||
} | ||
return int(r0), nil | ||
} | ||
|
||
func SchedYield() error { | ||
_, _, e1 := unix.Syscall(unix.SYS_SCHED_YIELD, 0, 0, 0) | ||
if e1 != 0 { | ||
return syscall.Errno(e1) | ||
} | ||
return nil | ||
} | ||
|
||
func SchedGetParam(pid int) (SchedParam, error) { | ||
var param SchedParam | ||
_, _, e1 := unix.Syscall(unix.SYS_SCHED_GETPARAM, uintptr(pid), uintptr(unsafe.Pointer(¶m)), 0) | ||
if e1 != 0 { | ||
return param, syscall.Errno(e1) | ||
} | ||
return param, nil | ||
} | ||
|
||
func SchedSetParam(pid int, param SchedParam) error { | ||
_, _, e1 := unix.Syscall(unix.SYS_SCHED_SETPARAM, uintptr(pid), uintptr(unsafe.Pointer(¶m)), 0) | ||
if e1 != 0 { | ||
return syscall.Errno(e1) | ||
} | ||
return nil | ||
} | ||
|
||
type SchedAttr struct { | ||
Size uint32 | ||
SchedPolicy Policy | ||
SchedFlags uint64 | ||
SchedNice uint32 | ||
SchedPriority uint32 | ||
SchedRuntime uint64 | ||
SchedDeadline uint64 | ||
SchedPeriod uint64 | ||
SchedUtilMin uint32 | ||
SchedUtilMax uint32 | ||
} | ||
|
||
func SchedGetAttr(pid int) (SchedAttr, error) { | ||
var attr SchedAttr | ||
_, _, e1 := unix.Syscall6(unix.SYS_SCHED_GETATTR, uintptr(pid), uintptr(unsafe.Pointer(&attr)), unsafe.Sizeof(SchedAttr{}), 0, 0, 0) | ||
if e1 != 0 { | ||
return attr, syscall.Errno(e1) | ||
} | ||
return attr, nil | ||
} | ||
|
||
func SchedSetAttr(pid int, attr SchedAttr, flags SchedFlag) error { | ||
attr.Size = uint32(unsafe.Sizeof(attr)) | ||
_, _, e1 := unix.Syscall(unix.SYS_SCHED_SETATTR, uintptr(pid), uintptr(unsafe.Pointer(&attr)), uintptr(flags)) | ||
if e1 != 0 { | ||
return syscall.Errno(e1) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
package tests | ||
|
||
import ( | ||
"errors" | ||
"os" | ||
"runtime" | ||
"strconv" | ||
"syscall" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
var CONFIG_RT_GROUP_SCHED bool = true | ||
|
||
func init() { | ||
runtime.LockOSThread() | ||
|
||
if v := os.Getenv("CONFIG_RT_GROUP_SCHED"); v != "" { | ||
if vv, err := strconv.ParseBool(v); err == nil { | ||
CONFIG_RT_GROUP_SCHED = vv | ||
} | ||
} | ||
} | ||
|
||
func TestGetSetScheduler(t *testing.T) { | ||
_, err := SchedGetScheduler(1 << 30) | ||
require.Error(t, err) | ||
|
||
pid := os.Getpid() | ||
s, err := SchedGetScheduler(pid) | ||
require.NoError(t, err) | ||
require.Equal(t, SCHED_NORMAL, s) | ||
|
||
// priority | ||
err = SchedSetScheduler(pid, SCHED_RR, SchedParam{ | ||
sched_priority: 100, | ||
}) | ||
require.True(t, errors.Is(err, syscall.EINVAL)) | ||
|
||
err = SchedSetScheduler(pid, SCHED_RR, SchedParam{ | ||
sched_priority: 90, | ||
}) | ||
require.True(t, !errors.Is(err, syscall.EINVAL)) | ||
|
||
if CONFIG_RT_GROUP_SCHED { | ||
t.Logf("skipping scheduler set checks") | ||
} else { | ||
require.NoError(t, err) | ||
|
||
s, err := SchedGetScheduler(pid) | ||
require.NoError(t, err) | ||
require.Equal(t, SCHED_RR, s) | ||
|
||
p, err := SchedGetParam(pid) | ||
require.NoError(t, err) | ||
require.Equal(t, 90, int(p.sched_priority)) | ||
} | ||
|
||
err = SchedSetScheduler(pid, SCHED_IDLE, SchedParam{}) | ||
require.NoError(t, err) | ||
|
||
s, err = SchedGetScheduler(pid) | ||
require.NoError(t, err) | ||
require.Equal(t, SCHED_IDLE, s) | ||
|
||
err = SchedSetScheduler(pid, SCHED_NORMAL, SchedParam{}) | ||
require.NoError(t, err) | ||
} | ||
|
||
func TestSchedMinMax(t *testing.T) { | ||
p, err := SchedGetPriorityMin(SCHED_RR) | ||
require.NoError(t, err) | ||
require.Equal(t, 1, p) | ||
|
||
p, err = SchedGetPriorityMax(SCHED_RR) | ||
require.NoError(t, err) | ||
require.Equal(t, 99, p) | ||
|
||
p, err = SchedGetPriorityMax(SCHED_BATCH) | ||
require.NoError(t, err) | ||
require.Equal(t, 0, p) | ||
} | ||
|
||
func TestSchedYield(t *testing.T) { | ||
err := SchedYield() | ||
require.NoError(t, err) | ||
} | ||
|
||
func TestSchedGetSetParam(t *testing.T) { | ||
pid := os.Getpid() | ||
|
||
p, err := SchedGetParam(pid) | ||
require.NoError(t, err) | ||
|
||
require.Equal(t, 0, int(p.sched_priority)) | ||
|
||
err = SchedSetParam(pid, SchedParam{}) | ||
require.NoError(t, err) | ||
|
||
if CONFIG_RT_GROUP_SCHED { | ||
t.Logf("skipping setting sched_priority") | ||
} else { | ||
err = SchedSetScheduler(pid, SCHED_RR, SchedParam{sched_priority: 50}) | ||
require.NoError(t, err) | ||
|
||
p, err := SchedGetParam(pid) | ||
require.NoError(t, err) | ||
|
||
require.Equal(t, 50, int(p.sched_priority)) | ||
} | ||
} | ||
|
||
func TestSchedAttr(t *testing.T) { | ||
pid := os.Getpid() | ||
|
||
if !CONFIG_RT_GROUP_SCHED { | ||
err := SchedSetScheduler(pid, SCHED_RR, SchedParam{sched_priority: 50}) | ||
require.NoError(t, err) | ||
} | ||
|
||
attr, err := SchedGetAttr(pid) | ||
require.NoError(t, err) | ||
|
||
require.True(t, attr.Size >= 0x30) | ||
|
||
if CONFIG_RT_GROUP_SCHED { | ||
require.Equal(t, SCHED_NORMAL, attr.SchedPolicy) | ||
|
||
attr := SchedAttr{SchedPolicy: SCHED_IDLE} | ||
err := SchedSetAttr(pid, attr, 0) | ||
require.NoError(t, err) | ||
|
||
attr, err = SchedGetAttr(pid) | ||
require.NoError(t, err) | ||
require.Equal(t, SCHED_IDLE, attr.SchedPolicy) | ||
|
||
t.Logf("skipping setting attr priority") | ||
} else { | ||
require.Equal(t, SCHED_RR, attr.SchedPolicy) | ||
require.Equal(t, 50, int(attr.SchedPriority)) | ||
|
||
attr := SchedAttr{SchedPolicy: SCHED_RR, SchedPriority: 60} | ||
err := SchedSetAttr(pid, attr, 0) | ||
require.NoError(t, err) | ||
|
||
attr, err = SchedGetAttr(pid) | ||
require.NoError(t, err) | ||
require.Equal(t, SCHED_RR, attr.SchedPolicy) | ||
require.Equal(t, 60, int(attr.SchedPriority)) | ||
} | ||
} |