5 Commits
v1.0 ... v1.3

119 changed files with 9690 additions and 5094 deletions

2
.gitignore vendored
View File

@@ -1 +1 @@
reniced /reniced

View File

@@ -2,10 +2,7 @@ run:
tests: false tests: false
modules-download-mode: readonly modules-download-mode: readonly
allow-parallel-runners: true allow-parallel-runners: true
go: '1.21' go: '1.22'
issues:
skip-dirs:
- vendor
output: output:
sort-results: true sort-results: true
linters: linters:
@@ -27,14 +24,13 @@ linters:
- errchkjson - errchkjson
- errorlint - errorlint
- exhaustive - exhaustive
- exportloopref - copyloopvar
- ginkgolinter - ginkgolinter
- gci - gci
- gocheckcompilerdirectives - gocheckcompilerdirectives
- gocritic - gocritic
- godot - godot
- gofmt - gofmt
- goimports
- gosec - gosec
- gosmopolitan - gosmopolitan
- grouper - grouper
@@ -59,5 +55,11 @@ linters:
- wastedassign - wastedassign
- whitespace - whitespace
- wsl - wsl
linters-settings:
govet:
enable-all: true
disable:
- nilness
- fieldalignment
# vim: set ft=yaml noet ai ts=4 sw=4 sts=4: # vim: set ft=yaml noet ai ts=4 sw=4 sts=4:

View File

@@ -4,8 +4,23 @@ daemon: true
# PID file for daemon. # PID file for daemon.
pidfile: /var/run/reniced.pid pidfile: /var/run/reniced.pid
# Delay among iterations. # Delay between process list update task consecutive runs.
loop_delay: 5000 process_list_update_period: 5000
# Delay between kill consecutive tasks.
process_kill_period: 5000
# Delay between changing niceness consecutive tasks.
process_nice_period: 5000
# Delay between changing io niceness consecutive tasks (linux-only).
process_ionice_period: 5000
# Period of time between consecutive periodic_process list tasks hammering.
periodic_process_invocation_period: 60000
# Period of time between process exec() invocations.
periodic_process_invocation_delay: 500
# Whether to print debug messages to stdout. # Whether to print debug messages to stdout.
debug: true debug: true
@@ -15,7 +30,11 @@ max_workers: 3
# Capacity of non-blocking tasks. All tasks that exceeding this capacity will block submission of new tasks until queue # Capacity of non-blocking tasks. All tasks that exceeding this capacity will block submission of new tasks until queue
# has vacant place for new task. # has vacant place for new task.
nb_capacity: 30 nb_capacity: 3000
# Time to time run these commands.
periodic_process:
- ps xa
kill: kill:
- sig: stop - sig: stop

View File

@@ -1,15 +1,14 @@
#!/usr/bin/env gmake -f #!/usr/bin/env gmake -f
BUILDOPTS=-ldflags="-s -w" -a -gcflags=all=-l -trimpath
BINARY=reniced BINARY=reniced
BUILDOPTS=-ldflags="-s -w" -a -gcflags=all="-l -B" -trimpath -buildvcs=false
all: clean build all: clean build
build: build:
go build ${BUILDOPTS} -o ${BINARY} go build ${BUILDOPTS} -o ${BINARY} ./cmd/${BINARY}
clean: clean:
go clean $(RM) ${BINARY}
upgrade: upgrade:
$(RM) -r vendor $(RM) -r vendor

92
cmd/reniced/main.go Normal file
View File

@@ -0,0 +1,92 @@
package main
import (
"fmt"
"log"
"os"
"os/signal"
"syscall"
lib "reniced/internal/lib"
"github.com/alitto/pond"
"github.com/sevlyar/go-daemon"
)
// main основная функция программы.
func main() {
var (
err error
cnf = lib.Config{
SigChan: make(chan os.Signal, 1),
KillSignal: make(map[string]syscall.Signal),
Renice: make(map[string]int),
IoreniceClass: make(map[string]uint32),
IoreniceClassdata: make(map[string]uint32),
NotImplementedError: fmt.Errorf("SYSCALL Not Implemented on current platform"),
ClassToString: map[uint32]string{
lib.IOPRIO_CLASS_NONE: "none",
lib.IOPRIO_CLASS_RT: "realtime",
lib.IOPRIO_CLASS_BE: "best-effort",
lib.IOPRIO_CLASS_IDLE: "idle",
},
StringToClass: map[string]uint32{
"none": lib.IOPRIO_CLASS_NONE,
"0": lib.IOPRIO_CLASS_NONE,
"realtime": lib.IOPRIO_CLASS_RT,
"1": lib.IOPRIO_CLASS_RT,
"best-effort": lib.IOPRIO_CLASS_BE,
"2": lib.IOPRIO_CLASS_BE,
"idle": lib.IOPRIO_CLASS_IDLE,
"3": lib.IOPRIO_CLASS_IDLE,
},
}
)
// Самое время поставить траппер сигналов.
signal.Notify(cnf.SigChan,
syscall.SIGINT,
syscall.SIGTERM,
syscall.SIGQUIT)
go cnf.SigHandler()
err = cnf.ReadConf()
if err != nil {
log.Fatalf("unable to parse config: %s", err)
}
// Создаём пул со статическим количеством воркеров и длиной очереди неблокируемых задач, равной NbCapacity.
cnf.Pool = pond.New(
cnf.MaxWorkers,
cnf.NbCapacity,
pond.Strategy(pond.Lazy()),
)
defer cnf.Pool.StopAndWait()
if cnf.Daemon {
cntxt := &daemon.Context{
WorkDir: "/",
Args: []string{"reniced"},
}
if cnf.Pidfile != "" {
cntxt.PidFileName = cnf.Pidfile
}
if d, err := cntxt.Reborn(); err != nil {
log.Fatalf("Unable to run: %s", err) //nolint: gocritic
} else if d != nil {
return
}
defer cntxt.Release() //nolint: errcheck
}
// То, ради чего всё затевалось.
cnf.Reniced()
}
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */

View File

@@ -1,54 +0,0 @@
package main
import (
"fmt"
"os"
"syscall"
"github.com/alitto/pond"
)
// Пул воркеров.
var pool *pond.WorkerPool
// Канал, в который приходят уведомления для хэндлера сигналов от траппера сигналов.
var sigChan = make(chan os.Signal, 1)
var kill = make(map[string]syscall.Signal)
var renice = make(map[string]int)
var ioreniceClass = make(map[string]uint32)
var ioreniceClassdata = make(map[string]uint32)
var NotImplementedError = fmt.Errorf("SYSCALL Not Implemented on current platform") //nolint:revive,stylecheck
const IOPRIO_CLASS_NONE = uint32(0) //nolint:revive,stylecheck
const IOPRIO_CLASS_RT = uint32(1) //nolint:revive,stylecheck
const IOPRIO_CLASS_BE = uint32(2) //nolint:revive,stylecheck
const IOPRIO_CLASS_IDLE = uint32(3) //nolint:revive,stylecheck
const IOPRIO_WHO_PROCESS = 1 //nolint:revive,stylecheck
const IOPRIO_WHO_PGRP = 2 //nolint:revive,stylecheck
const IOPRIO_WHO_USER = 3 //nolint:revive,stylecheck
const IOPRIO_CLASS_SHIFT = uint32(13) //nolint:revive,stylecheck
const IOPRIO_PRIO_MASK = ((uint32(1) << IOPRIO_CLASS_SHIFT) - 1) //nolint:revive,stylecheck
var ClassToString = map[uint32]string{
IOPRIO_CLASS_NONE: "none",
IOPRIO_CLASS_RT: "realtime",
IOPRIO_CLASS_BE: "best-effort",
IOPRIO_CLASS_IDLE: "idle",
}
var StringToClass = map[string]uint32{
"none": IOPRIO_CLASS_NONE,
"0": IOPRIO_CLASS_NONE,
"realtime": IOPRIO_CLASS_RT,
"1": IOPRIO_CLASS_RT,
"best-effort": IOPRIO_CLASS_BE,
"2": IOPRIO_CLASS_BE,
"idle": IOPRIO_CLASS_IDLE,
"3": IOPRIO_CLASS_IDLE,
}
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */

18
go.mod
View File

@@ -1,22 +1,22 @@
module reniced module reniced
go 1.21.4 go 1.22.6
require ( require (
github.com/alitto/pond v1.8.3 github.com/alitto/pond v1.9.2
github.com/sevlyar/go-daemon v0.1.6 github.com/sevlyar/go-daemon v0.1.6
github.com/shirou/gopsutil/v3 v3.24.3 github.com/shirou/gopsutil/v3 v3.24.5
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )
require ( require (
github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/sys v0.19.0 // indirect golang.org/x/sys v0.20.0 // indirect
) )

39
go.sum
View File

@@ -1,61 +1,44 @@
github.com/alitto/pond v1.8.3 h1:ydIqygCLVPqIX/USe5EaV/aSRXTRXDEI9JwuDdu+/xs= github.com/alitto/pond v1.9.2 h1:9Qb75z/scEZVCoSU+osVmQ0I0JOeLfdTDafrbcJ8CLs=
github.com/alitto/pond v1.8.3/go.mod h1:CmvIIGd5jKLasGI3D87qDkQxjzChdKMmnXMg3fG6M6Q= github.com/alitto/pond v1.9.2/go.mod h1:xQn3P/sHTYcU/1BR3i86IGIrilcrGC2LiS+E2+CJWsI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a h1:3Bm7EwfUQUvhNeKIkUct/gl9eod1TcXuj8stxvi/GoI=
github.com/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/sevlyar/go-daemon v0.1.6 h1:EUh1MDjEM4BI109Jign0EaknA2izkOyi0LV3ro3QQGs= github.com/sevlyar/go-daemon v0.1.6 h1:EUh1MDjEM4BI109Jign0EaknA2izkOyi0LV3ro3QQGs=
github.com/sevlyar/go-daemon v0.1.6/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE= github.com/sevlyar/go-daemon v0.1.6/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE=
github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg= github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4=
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 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/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

15
internal/lib/constants.go Normal file
View File

@@ -0,0 +1,15 @@
package lib
const IOPRIO_CLASS_NONE = uint32(0) //nolint:revive,stylecheck
const IOPRIO_CLASS_RT = uint32(1) //nolint:revive,stylecheck
const IOPRIO_CLASS_BE = uint32(2) //nolint:revive,stylecheck
const IOPRIO_CLASS_IDLE = uint32(3) //nolint:revive,stylecheck
const IOPRIO_WHO_PROCESS = 1 //nolint:revive,stylecheck
const IOPRIO_WHO_PGRP = 2 //nolint:revive,stylecheck
const IOPRIO_WHO_USER = 3 //nolint:revive,stylecheck
const IOPRIO_CLASS_SHIFT = uint32(13) //nolint:revive,stylecheck
const IOPRIO_PRIO_MASK = ((uint32(1) << IOPRIO_CLASS_SHIFT) - 1) //nolint:revive,stylecheck
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */

View File

@@ -1,4 +1,4 @@
package main package lib
func PrioToClass(prio uint32) uint32 { func PrioToClass(prio uint32) uint32 {
return prio >> IOPRIO_CLASS_SHIFT return prio >> IOPRIO_CLASS_SHIFT

View File

@@ -1,7 +1,7 @@
//go:build linux //go:build linux
// +build linux // +build linux
package main package lib
import ( import (
"fmt" "fmt"
@@ -20,7 +20,7 @@ func GetIOPriority(which int, who int) (uint32, error) {
) )
if e1 != 0 { if e1 != 0 {
err = fmt.Errorf(fmt.Sprintf("Received error number %v", e1)) err = fmt.Errorf("received error number %w", e1)
} }
return prio, err return prio, err
@@ -34,18 +34,18 @@ func SetIOPriority(which int, who int, prio uint32) error {
) )
if e1 != 0 { if e1 != 0 {
err = fmt.Errorf(fmt.Sprintf("Received error number %v", e1)) err = fmt.Errorf("received error number %w", e1)
} }
return err return err
} }
// IORenice выставляет процессу приоритет для операций ввода-вывода. // IORenice выставляет процессу приоритет для операций ввода-вывода.
func IORenice(cnf Config, p *proc.Process, processName string) { func (cnf Config) IORenice(p *proc.Process, processName string) {
if currentIOPrioLevel, err := GetIOPriority(IOPRIO_WHO_PROCESS, int(p.Pid)); err == nil { if currentIOPrioLevel, err := GetIOPriority(IOPRIO_WHO_PROCESS, int(p.Pid)); err == nil {
currentClass, currentClassdata := PrioToClassAndClassdata(currentIOPrioLevel) currentClass, currentClassdata := PrioToClassAndClassdata(currentIOPrioLevel)
class := ioreniceClass[processName] class := cnf.IoreniceClass[processName]
classdata := ioreniceClassdata[processName] classdata := cnf.IoreniceClassdata[processName]
if class == currentClass && classdata == currentClassdata { if class == currentClass && classdata == currentClassdata {
if cnf.Debug && currentIOPrioLevel != 0 { // 0 - это дефолтный уровень io niceness. if cnf.Debug && currentIOPrioLevel != 0 { // 0 - это дефолтный уровень io niceness.

View File

@@ -0,0 +1,16 @@
//go:build !linux
// +build !linux
package lib
import proc "github.com/shirou/gopsutil/v3/process"
func (cnf Config) GetIOPriority(which int, who int) (prio uint32, err error) {
return 0, cnf.NotImplementedError
}
func (cnf Config) SetIOPriority(which int, who int, prio uint32) (err error) {
return cnf.NotImplementedError
}
func (cnf Config) IORenice(p *proc.Process, processName string) {}

166
internal/lib/reniced.go Normal file
View File

@@ -0,0 +1,166 @@
package lib
import (
"log"
"math"
"os/exec"
"runtime"
"strings"
"syscall"
"time"
proc "github.com/shirou/gopsutil/v3/process"
)
// reniced основная логика.
func (cnf Config) Reniced() {
var (
processListUpdateTimer *time.Ticker
processKillTimer *time.Ticker
processReniceTimer *time.Ticker
processIONiceTimer *time.Ticker
processListTimer *time.Ticker
processList []*proc.Process
err error
)
// Прежде всего настроим таймеры
processListUpdateTimer = time.NewTicker(time.Duration(cnf.ProcessListUpdatePeriod) * time.Millisecond)
processReniceTimer = time.NewTicker(time.Duration(cnf.ProcessNicePeriod) * time.Millisecond)
processKillTimer = time.NewTicker(time.Duration(cnf.ProcessKillPeriod) * time.Millisecond)
processIONiceTimer = time.NewTicker(time.Duration(cnf.ProcessIONicePeriod) * time.Millisecond)
processListTimer = time.NewTicker(time.Duration(cnf.PeriodicProcessInvocationPeriod) * time.Millisecond)
for {
select {
// Обновляем список процессов.
case <-processListUpdateTimer.C:
processList, err = proc.Processes()
if err != nil {
log.Fatalf("Unable to get process list: %s", err)
}
// Проходим по списку процессов и посылаем сигналы процессам.
case <-processKillTimer.C:
for _, p := range processList {
ok := cnf.Pool.TrySubmit(func() {
if processName, err := p.Name(); err == nil {
// Посылаем процессу сигналы, если таковые есть в конфиге.
if killSignal := cnf.KillSignal[processName]; killSignal != 0 {
switch killSignal { //nolint:exhaustive
case syscall.SIGSTOP:
_ = p.SendSignal(killSignal)
if cnf.Debug {
log.Printf(
"Matching processName with killProcessname %s(%d), SIG%s sent",
processName,
p.Pid,
strings.ToUpper(killSignal.String()),
)
}
default:
_ = p.SendSignal(killSignal)
if cnf.Debug {
log.Printf(
"Matching processName with killProcessname %s(%d), SIG%s sent",
processName,
p.Pid,
strings.ToUpper(killSignal.String()),
)
}
}
}
}
})
if !ok {
log.Printf("Unable to add task to pool. Increase nb_capacity?")
}
}
// Проходим по списку процессов и меняем ionice процессам.
case <-processIONiceTimer.C:
for _, p := range processList {
ok := cnf.Pool.TrySubmit(func() {
if processName, err := p.Name(); err == nil {
cnf.IORenice(p, processName)
}
})
if !ok {
log.Printf("Unable to add task to pool. Increase nb_capacity?")
}
}
// Проходим по списку того, что надо запустить и запускаем.
case <-processListTimer.C:
for _, v := range cnf.PeriodicProcesses {
log.Printf("Invoking command: %s", v)
exec.Command(v)
time.Sleep(time.Duration(cnf.PeriodicProcessInvocationDelay) * time.Millisecond)
}
// Проходим по списку процессов и меняем ionice процессам.
case <-processReniceTimer.C:
// Не самый эффективный, зато работающий способ - простой перебор массивов.
for _, p := range processList {
ok := cnf.Pool.TrySubmit(func() {
if processName, err := p.Name(); err == nil {
// Для каждого процесса извлекаем его текущий priority.
if currentPrioLevel, err := syscall.Getpriority(syscall.PRIO_PROCESS, int(p.Pid)); err == nil {
if niceLevel := cnf.Renice[processName]; niceLevel != 0 {
prioLevel := niceLevel
currentNiceLevel := currentPrioLevel
if runtime.GOOS == "linux" {
// Value of PR = 20 + (-20 to +19) is 0 to 39
switch {
case niceLevel > 0:
prioLevel = 20 - niceLevel
case niceLevel < 0:
prioLevel = 20 + int(math.Abs(float64(niceLevel)))
default:
prioLevel = 20
}
currentNiceLevel = 20 - currentPrioLevel
}
if currentPrioLevel != prioLevel {
// on Linux Setpriority actually operates niceness value.
_ = syscall.Setpriority(syscall.PRIO_PROCESS, int(p.Pid), niceLevel)
if cnf.Debug {
log.Printf(
"Set niceness for %s(%d) to %d (was %d)",
processName,
p.Pid,
niceLevel,
currentNiceLevel,
)
}
} else if cnf.Debug {
log.Printf(
"Niceness for %s(%d) already set to %d",
processName,
p.Pid,
niceLevel,
)
}
}
}
}
})
if !ok {
log.Printf("Unable to add task to pool. Increase nb_capacity?")
}
}
}
}
// Мы сюда никогда не попадём.
// pool.StopAndWait()
} //nolint:wsl
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */

View File

@@ -0,0 +1,30 @@
package lib
import (
"log"
"os"
"syscall"
)
// sigHandler хэндлер сигналов. Работает на выходе приложения. Держит INT, TERM, QUIT.
func (cnf Config) SigHandler() {
for {
var s = <-cnf.SigChan
switch s {
case syscall.SIGINT:
log.Print("Got SIGINT, quitting")
case syscall.SIGTERM:
log.Print("Got SIGTERM, quitting")
case syscall.SIGQUIT:
log.Print("Got SIGQUIT, quitting")
// Заходим на новую итерацию, если у нас "неинтересный" сигнал
default:
continue
}
os.Exit(0)
}
}
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */

89
internal/lib/types.go Normal file
View File

@@ -0,0 +1,89 @@
package lib
import (
"os"
"syscall"
"github.com/alitto/pond"
)
type Config struct {
// Пул воркеров.
Pool *pond.WorkerPool
KillSignal map[string]syscall.Signal
Renice map[string]int
IoreniceClass map[string]uint32
IoreniceClassdata map[string]uint32
ClassToString map[uint32]string
StringToClass map[string]uint32
// Канал, в который приходят уведомления для хэндлера сигналов от траппера сигналов.
SigChan chan os.Signal
NotImplementedError error
// Weather we fork to backgoround or stay as-is.
Daemon bool `yaml:"daemon,omitempty"`
// Where to put pid-file.
Pidfile string `yaml:"pidfile,omitempty"`
// ProcessListUpdatePeriod - delay between process list update task consecutive runs.
ProcessListUpdatePeriod int `yaml:"process_list_update_period,omitempty"`
// ProcessKillPeriod in milliseconds - delay between kill consecutive tasks.
ProcessKillPeriod int `yaml:"process_kill_period,omitempty"`
// ProcessNicePeriod in milliseconds - delay between changing niceness consecutive tasks.
ProcessNicePeriod int `yaml:"process_nice_period,omitempty"`
// ProcessNicePeriod in milliseconds - delay between changing io niceness consecutive tasks (linux-only).
ProcessIONicePeriod int `yaml:"process_ionice_period,omitempty"`
// PeriodicProcessInvocationPeriod in milliseconds - delay between PeriodicProcesses invocations.
PeriodicProcessInvocationPeriod int `yaml:"periodic_process_invocation_period,omitempty"`
// PriodicProcessInvocationDelay in milliseconds - delay between each process calling in PeriodicProcesses list.
PeriodicProcessInvocationDelay int `yaml:"periodic_process_invocation_delay,omitempty"`
// PeriodicProcesses list of processes that should be executed priodically.
PeriodicProcesses []string `yaml:"periodic_process,omitempty"`
// Whether to print debug info on stdout.
Debug bool `yaml:"debug,omitempty"`
// Maximum workers in pool.
MaxWorkers int `yaml:"max_workers,omitempty"`
// Capacity of non-blocking tasks. All tasks that exceeding this capacity will block submission of new tasks until
// queue has vacant place for new task.
NbCapacity int `yaml:"nb_capacity,omitempty"`
// В гошке yaml не позволяет сделать удобный парсер для конструкций, аналогичных json-овскому
// {kill:{"stop":["proc1","proc2"], "term":["proc3","proc4"]}}
// Поэтому мы просто возьмём массив и каждому элементу добавим тип сигнала.
Kill Kill `yaml:"kill,omitempty"`
Prio Prio `yaml:"prio,omitempty"`
IOPrio IOPrio `yaml:"ioprio,omitempty"`
}
type Prio []struct {
Nice int `yaml:"nice,omitempty"`
Name []string `yaml:"name,omitempty"`
}
type Kill []struct {
Sig string `yaml:"sig,omitempty"`
Name []string `yaml:"name,omitempty"`
}
type IOPrio []struct {
Class uint32 `yaml:"class,omitempty"`
Prio uint32 `yaml:"prio,omitempty"`
Name []string `yaml:"name,omitempty"`
}
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */

View File

@@ -1,4 +1,4 @@
package main package lib
import ( import (
"fmt" "fmt"
@@ -14,9 +14,8 @@ import (
// readConf вычиляет, от какого пользователя запущен процесс и в зависимости от результата, скармливает readConfFile тот // readConf вычиляет, от какого пользователя запущен процесс и в зависимости от результата, скармливает readConfFile тот
// или иной путь, по которому предположительно лежит конфиг. // или иной путь, по которому предположительно лежит конфиг.
func readConf() (Config, error) { func (cnf *Config) ReadConf() error {
var ( var (
cnf Config
err error err error
) )
@@ -32,65 +31,92 @@ func readConf() (Config, error) {
log.Fatalln("Unable to get HOME environment variable value") log.Fatalln("Unable to get HOME environment variable value")
} }
cnf, err = readConfFile(os.Getenv("HOME") + "/.reniced.yaml") err = cnf.readConfFile(os.Getenv("HOME") + "/.reniced.yaml")
} else { } else {
cnf, err = readConfFile("/etc/reniced.yaml") if runtime.GOOS == "freebsd" {
err = cnf.readConfFile("/usr/local/etc/reniced.yaml")
} else {
err = cnf.readConfFile("/etc/reniced.yaml")
}
} }
return cnf, err return err
} }
// readConfFile парсит даденный конфиг в глобальную структуру, с которой работает программа. // readConfFile парсит даденный конфиг в глобальную структуру, с которой работает программа.
func readConfFile(path string) (Config, error) { func (cnf *Config) readConfFile(path string) error {
var cfg Config
fileInfo, err := os.Stat(path) fileInfo, err := os.Stat(path)
// Предполагаем, что файла либо нет, либо мы не можем его прочитать, второе надо бы логгировать, но пока забьём. // Предполагаем, что файла либо нет, либо мы не можем его прочитать, второе надо бы логгировать, но пока забьём.
if err != nil { if err != nil {
return Config{}, err return err
} }
// Конфиг-файл длинноват для конфига, попробуем следующего кандидата. // Конфиг-файл длинноват для конфига, попробуем следующего кандидата.
if fileInfo.Size() > 65535 { if fileInfo.Size() > 65535 {
err := fmt.Errorf("config file %s is too long for config, skipping", path) err = fmt.Errorf("config file %s is too long for config, skipping", path)
return Config{}, err return err
} }
buf, err := os.ReadFile(path) buf, err := os.ReadFile(path)
// Не удалось прочитать. // Не удалось прочитать.
if err != nil { if err != nil {
return Config{}, err return err
} }
if err = yaml.Unmarshal(buf, &cfg); err != nil { if err = yaml.Unmarshal(buf, &cnf); err != nil {
return Config{}, err return err
} }
if cfg.LoopDelay == 0 { if cnf.ProcessListUpdatePeriod == 0 {
cfg.LoopDelay = 2000 cnf.ProcessListUpdatePeriod = 5000
log.Printf("loop_delay set to %d milliseconds", cfg.LoopDelay) log.Printf("process_list_update_priod set to %d milliseconds", cnf.ProcessListUpdatePeriod)
} }
if cfg.Debug { if cnf.ProcessNicePeriod == 0 {
cnf.ProcessNicePeriod = 5000
log.Printf("process_nice_priod set to %d milliseconds", cnf.ProcessNicePeriod)
}
if cnf.ProcessIONicePeriod == 0 {
cnf.ProcessIONicePeriod = 5000
log.Printf("process_ionice_period set to %d milliseconds", cnf.ProcessIONicePeriod)
}
if cnf.ProcessKillPeriod == 0 {
cnf.ProcessKillPeriod = 5000
log.Printf("process_kill_period set to %d milliseconds", cnf.ProcessIONicePeriod)
}
if cnf.PeriodicProcessInvocationPeriod == 0 {
cnf.PeriodicProcessInvocationPeriod = 60000
log.Printf("periodic_process_invocation_period set to %d milliseconds", cnf.PeriodicProcessInvocationPeriod)
}
if cnf.PeriodicProcessInvocationDelay == 0 {
cnf.PeriodicProcessInvocationDelay = 500
log.Printf("periodic_process_invocation_delay set to %d milliseconds", cnf.PeriodicProcessInvocationDelay)
}
if cnf.Debug {
log.Println("debug set to true") log.Println("debug set to true")
} }
if cfg.MaxWorkers == 0 { if cnf.MaxWorkers == 0 {
cfg.MaxWorkers = 5 cnf.MaxWorkers = runtime.NumCPU()
log.Printf("max_workers set to %d", cfg.MaxWorkers) log.Printf("max_workers set to %d", cnf.MaxWorkers)
} }
if cfg.NbCapacity == 0 { if cnf.NbCapacity == 0 {
cfg.NbCapacity = 100 cnf.NbCapacity = 100
log.Printf("nb_capacity set to %d", cfg.NbCapacity) log.Printf("nb_capacity set to %d", cnf.NbCapacity)
} }
if cfg.NbCapacity < cfg.MaxWorkers { if cnf.NbCapacity < cnf.MaxWorkers {
cfg.NbCapacity = cfg.MaxWorkers cnf.NbCapacity = cnf.MaxWorkers
log.Printf("nb_capacity set to same value as max_workers: %d", cfg.MaxWorkers) log.Printf("nb_capacity set to same value as max_workers: %d", cnf.MaxWorkers)
} }
// Обычный юзер не может задрать nice больше 0, только руту такое можно. // Обычный юзер не может задрать nice больше 0, только руту такое можно.
@@ -100,13 +126,13 @@ func readConfFile(path string) (Config, error) {
maxNice = -20 maxNice = -20
} }
for _, v := range cfg.Prio { for _, v := range cnf.Prio {
switch { switch {
case len(v.Name) != 0 && (v.Nice < 20 && v.Nice > maxNice): case len(v.Name) != 0 && (v.Nice < 20 && v.Nice > maxNice):
for _, procName := range v.Name { for _, procName := range v.Name {
renice[procName] = v.Nice cnf.Renice[procName] = v.Nice
if cfg.Debug { if cnf.Debug {
log.Printf("Add %s to list of nicelevel %d processes.", procName, v.Nice) log.Printf("Add %s to list of nicelevel %d processes.", procName, v.Nice)
} }
} }
@@ -117,7 +143,7 @@ func readConfFile(path string) (Config, error) {
} }
} }
for _, v := range cfg.IOPrio { for _, v := range cnf.IOPrio {
switch { switch {
case len(v.Name) == 0: case len(v.Name) == 0:
log.Println("Skipping empty name entry in ioprio config block") log.Println("Skipping empty name entry in ioprio config block")
@@ -133,10 +159,10 @@ func readConfFile(path string) (Config, error) {
log.Printf("Skipping entry %s with class 2 and prio > 7 in ioprio config block", v.Name) log.Printf("Skipping entry %s with class 2 and prio > 7 in ioprio config block", v.Name)
default: default:
for _, processName := range v.Name { for _, processName := range v.Name {
ioreniceClass[processName] = v.Class cnf.IoreniceClass[processName] = v.Class
ioreniceClassdata[processName] = v.Prio cnf.IoreniceClassdata[processName] = v.Prio
if cfg.Debug { if cnf.Debug {
log.Printf("Add %s to list of ionice class %d processes.", processName, v.Class) log.Printf("Add %s to list of ionice class %d processes.", processName, v.Class)
log.Printf("Add %s to list of ionice prio %d processes.", processName, v.Prio) log.Printf("Add %s to list of ionice prio %d processes.", processName, v.Prio)
} }
@@ -144,35 +170,35 @@ func readConfFile(path string) (Config, error) {
} }
} }
for _, v := range cfg.Kill { for _, v := range cnf.Kill {
if len(v.Name) != 0 { if len(v.Name) != 0 {
switch v.Sig { switch v.Sig {
case "kill", "stop", "term", "int", "quit", "abrt", "hup", "usr1", "usr2": case "kill", "stop", "term", "int", "quit", "abrt", "hup", "usr1", "usr2":
for _, procName := range v.Name { for _, procName := range v.Name {
switch v.Sig { switch v.Sig {
case "kill": case "kill":
kill[procName] = syscall.SIGKILL cnf.KillSignal[procName] = syscall.SIGKILL
case "stop": case "stop":
kill[procName] = syscall.SIGSTOP cnf.KillSignal[procName] = syscall.SIGSTOP
case "term": case "term":
kill[procName] = syscall.SIGTERM cnf.KillSignal[procName] = syscall.SIGTERM
case "int": case "int":
kill[procName] = syscall.SIGINT cnf.KillSignal[procName] = syscall.SIGINT
case "quit": case "quit":
kill[procName] = syscall.SIGQUIT cnf.KillSignal[procName] = syscall.SIGQUIT
case "abrt": case "abrt":
kill[procName] = syscall.SIGABRT cnf.KillSignal[procName] = syscall.SIGABRT
case "hup": case "hup":
kill[procName] = syscall.SIGHUP cnf.KillSignal[procName] = syscall.SIGHUP
case "usr1": case "usr1":
kill[procName] = syscall.SIGUSR1 cnf.KillSignal[procName] = syscall.SIGUSR1
case "usr2": case "usr2":
kill[procName] = syscall.SIGUSR2 cnf.KillSignal[procName] = syscall.SIGUSR2
default: default:
continue continue
} }
if cfg.Debug { if cnf.Debug {
log.Printf( log.Printf(
"Add %s to list of processes that should be killed with SIG%s signal.", "Add %s to list of processes that should be killed with SIG%s signal.",
procName, procName,
@@ -188,7 +214,7 @@ func readConfFile(path string) (Config, error) {
} }
} }
return cfg, nil return nil
} }
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */ /* vim: set ft=go noet ai ts=4 sw=4 sts=4: */

View File

@@ -1,16 +0,0 @@
//go:build !linux
// +build !linux
package main
import proc "github.com/shirou/gopsutil/v3/process"
func GetIOPriority(which int, who int) (prio uint32, err error) {
return 0, NotImplementedError
}
func SetIOPriority(which int, who int, prio uint32) (err error) {
return NotImplementedError
}
func IORenice(cnf Config, p *proc.Process, processName string) {}

193
main.go
View File

@@ -1,193 +0,0 @@
package main
import (
"log"
"math"
"os"
"os/signal"
"runtime"
"strings"
"syscall"
"time"
"github.com/alitto/pond"
"github.com/sevlyar/go-daemon"
proc "github.com/shirou/gopsutil/v3/process"
)
// main основная функция программы.
func main() {
// Самое время поставить траппер сигналов.
signal.Notify(sigChan,
syscall.SIGINT,
syscall.SIGTERM,
syscall.SIGQUIT)
go sigHandler()
var (
cnf Config
err error
)
cnf, err = readConf()
if err != nil {
log.Fatalf("unable to parse config: %s", err)
}
if cnf.Daemon {
cntxt := &daemon.Context{
WorkDir: "/",
Args: []string{"reniced"},
}
if cnf.Pidfile != "" {
cntxt.PidFileName = cnf.Pidfile
}
if d, err := cntxt.Reborn(); err != nil {
log.Fatal("Unable to run: ", err)
return
} else if d != nil {
return
}
defer cntxt.Release() //nolint: errcheck
}
// То, ради чего всё затевалось.
reniced(cnf)
}
// reniced основная логика.
func reniced(cnf Config) {
// Создаём пул со статическим количеством воркеров и длиной очереди неблокируемых задач, равной NbCapacity.
pool = pond.New(cnf.MaxWorkers, cnf.NbCapacity, pond.Strategy(pond.Lazy()))
for {
processList, err := proc.Processes()
if err != nil {
log.Fatalf("Unable to get process list: %s", err)
}
// Не самый эффективный, зато работающий способ - простой перебор массивов.
for _, p := range processList {
ok := pool.TrySubmit(func() {
if processName, err := p.Name(); err == nil {
// Для каждого процесса извлекаем его текущий priority.
if currentPrioLevel, err := syscall.Getpriority(syscall.PRIO_PROCESS, int(p.Pid)); err == nil {
if niceLevel := renice[processName]; niceLevel != 0 {
prioLevel := niceLevel
currentNiceLevel := currentPrioLevel
if runtime.GOOS == "linux" {
// Value of PR = 20 + (-20 to +19) is 0 to 39
switch {
case niceLevel > 0:
prioLevel = 20 - niceLevel
case niceLevel < 0:
prioLevel = 20 + int(math.Abs(float64(niceLevel)))
default:
prioLevel = 20
}
currentNiceLevel = 20 - currentPrioLevel
}
if currentPrioLevel != prioLevel {
// on Linux Setpriority actually operates niceness value.
_ = syscall.Setpriority(syscall.PRIO_PROCESS, int(p.Pid), niceLevel)
if cnf.Debug {
log.Printf(
"Set niceness for %s(%d) to %d (was %d)",
processName,
p.Pid,
niceLevel,
currentNiceLevel,
)
}
} else if cnf.Debug {
log.Printf(
"Niceness for %s(%d) already set to %d",
processName,
p.Pid,
niceLevel,
)
}
}
}
IORenice(cnf, p, processName)
// Посылаем процессу сигналы, если таковые есть в конфиге.
if killSignal := kill[processName]; killSignal != 0 {
switch killSignal { //nolint:exhaustive
case syscall.SIGSTOP:
_ = p.SendSignal(killSignal)
if cnf.Debug {
log.Printf(
"Matching processName with killProcessname %s(%d), SIG%s sent",
processName,
p.Pid,
strings.ToUpper(killSignal.String()),
)
}
default:
_ = p.SendSignal(killSignal)
if cnf.Debug {
log.Printf(
"Matching processName with killProcessname %s(%d), SIG%s sent",
processName,
p.Pid,
strings.ToUpper(killSignal.String()),
)
}
}
}
}
})
if !ok {
log.Printf("Unable to add task to pool")
}
}
time.Sleep(time.Millisecond * time.Duration(cnf.LoopDelay))
}
// Мы сюда никогда не попадём.
// pool.StopAndWait()
} //nolint:wsl
// sigHandler хэндлер сигналов. Работает на выходе приложения. Держит INT, TERM, QUIT.
func sigHandler() {
for {
var s = <-sigChan
switch s {
case syscall.SIGINT:
log.Print("Got SIGINT, quitting")
case syscall.SIGTERM:
log.Print("Got SIGTERM, quitting")
case syscall.SIGQUIT:
log.Print("Got SIGQUIT, quitting")
// Заходим на новую итерацию, если у нас "неинтересный" сигнал
default:
continue
}
// Закрываем пул воркеров и освобождаем ресурсы.
pool.StopAndWait()
os.Exit(0)
}
}
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */

View File

@@ -1,49 +0,0 @@
package main
type Config struct {
// Weather we fork to backgoround or stay as-is.
Daemon bool `yaml:"daemon,omitempty"`
// Where to put pid-file.
Pidfile string `yaml:"pidfile,omitempty"`
// LoopDelay in milliseconds - whole set of action delay period.
LoopDelay int `yaml:"loop_delay,omitempty"`
// Whether to print debug info on stdout.
Debug bool `yaml:"debug,omitempty"`
// Maximum workers in pool.
MaxWorkers int `yaml:"max_workers,omitempty"`
// Capacity of non-blocking tasks. All tasks that exceeding this capacity will block submission of new tasks until
// queue has vacant place for new task.
NbCapacity int `yaml:"nb_capacity,omitempty"`
// В гошке yaml не позволяет сделать удобный парсер для конструкций, аналогичных json-овскому
// {kill:{"stop":["proc1","proc2"], "term":["proc3","proc4"]}}
// Поэтому мы просто возьмём массив и каждому элементу добавим тип сигнала.
Kill Kill `yaml:"kill,omitempty"`
Prio Prio `yaml:"prio,omitempty"`
IOPrio IOPrio `yaml:"ioprio,omitempty"`
}
type Prio []struct {
Nice int `yaml:"nice,omitempty"`
Name []string `yaml:"name,omitempty"`
}
type Kill []struct {
Sig string `yaml:"sig,omitempty"`
Name []string `yaml:"name,omitempty"`
}
type IOPrio []struct {
Class uint32 `yaml:"class,omitempty"`
Prio uint32 `yaml:"prio,omitempty"`
Name []string `yaml:"name,omitempty"`
}
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */

View File

@@ -193,17 +193,28 @@ func main() {
### Pool Configuration Options ### Pool Configuration Options
- **MinWorkers**: Specifies the minimum number of worker goroutines that must be running at any given time. These goroutines are started when the pool is created. The default value is 0. Example: #### MinWorkers
Specifies the minimum number of worker goroutines that must be running at any given time. These goroutines are started when the pool is created. The default value is 0. Example:
``` go ``` go
// This will create a pool with 5 running worker goroutines // This will create a pool with 5 running worker goroutines
pool := pond.New(10, 1000, pond.MinWorkers(5)) pool := pond.New(10, 1000, pond.MinWorkers(5))
``` ```
- **IdleTimeout**: Defines how long to wait before removing idle worker goroutines from the pool. The default value is 5 seconds. Example:
#### IdleTimeout
Defines how long to wait before removing idle worker goroutines from the pool. The default value is 5 seconds. Example:
``` go ``` go
// This will create a pool that will remove workers 100ms after they become idle // This will create a pool that will remove workers 100ms after they become idle
pool := pond.New(10, 1000, pond.IdleTimeout(100 * time.Millisecond)) pool := pond.New(10, 1000, pond.IdleTimeout(100 * time.Millisecond))
``` ```
- **PanicHandler**: Allows to configure a custom function to handle panics thrown by tasks submitted to the pool. The default handler just writes a message to standard output using `fmt.Printf` with the following contents: `Worker exits from a panic: [panic] \n Stack trace: [stack trace]`). Example:
#### PanicHandler
Allows to configure a custom function to handle panics thrown by tasks submitted to the pool. The default handler just writes a message to standard output using `fmt.Printf` with the following contents: `Worker exits from a panic: [panic] \n Stack trace: [stack trace]`). Example:
```go ```go
// Custom panic handler function // Custom panic handler function
panicHandler := func(p interface{}) { panicHandler := func(p interface{}) {
@@ -213,17 +224,26 @@ panicHandler := func(p interface{}) {
// This will create a pool that will handle panics using a custom panic handler // This will create a pool that will handle panics using a custom panic handler
pool := pond.New(10, 1000, pond.PanicHandler(panicHandler))) pool := pond.New(10, 1000, pond.PanicHandler(panicHandler)))
``` ```
- **Strategy**: Configures the strategy used to resize the pool when backpressure is detected. You can create a custom strategy by implementing the `pond.ResizingStrategy` interface or choose one of the 3 presets:
- **Eager**: maximizes responsiveness at the expense of higher resource usage, which can reduce throughput under certain conditions. This strategy is meant for worker pools that will operate at a small percentage of their capacity most of the time and may occasionally receive bursts of tasks. This is the default strategy. #### Strategy
- **Balanced**: tries to find a balance between responsiveness and throughput. It's suitable for general purpose worker pools or those that will operate close to 50% of their capacity most of the time.
- **Lazy**: maximizes throughput at the expense of responsiveness. This strategy is meant for worker pools that will operate close to their max. capacity most of the time. Configures the strategy used to resize the pool when backpressure is detected. You can create a custom strategy by implementing the `pond.ResizingStrategy` interface or choose one of the 3 presets:
- **Eager**: maximizes responsiveness at the expense of higher resource usage, which can reduce throughput under certain conditions. This strategy is meant for worker pools that will operate at a small percentage of their capacity most of the time and may occasionally receive bursts of tasks. This is the default strategy.
- **Balanced**: tries to find a balance between responsiveness and throughput. It's suitable for general purpose worker pools or those that will operate close to 50% of their capacity most of the time.
- **Lazy**: maximizes throughput at the expense of responsiveness. This strategy is meant for worker pools that will operate close to their max. capacity most of the time.
``` go ``` go
// Example: create pools with different resizing strategies // Example: create pools with different resizing strategies
eagerPool := pond.New(10, 1000, pond.Strategy(pond.Eager())) eagerPool := pond.New(10, 1000, pond.Strategy(pond.Eager()))
balancedPool := pond.New(10, 1000, pond.Strategy(pond.Balanced())) balancedPool := pond.New(10, 1000, pond.Strategy(pond.Balanced()))
lazyPool := pond.New(10, 1000, pond.Strategy(pond.Lazy())) lazyPool := pond.New(10, 1000, pond.Strategy(pond.Lazy()))
``` ```
- **Context**: Configures a parent context on this pool to stop all workers when it is cancelled. The default value `context.Background()`. Example:
#### Context
Configures a parent context on this pool to stop all workers when it is cancelled. The default value `context.Background()`. Example:
``` go ``` go
// This creates a pool that is stopped when myCtx is cancelled // This creates a pool that is stopped when myCtx is cancelled
pool := pond.New(10, 1000, pond.Context(myCtx)) pool := pond.New(10, 1000, pond.Context(myCtx))

8
vendor/github.com/alitto/pond/codecov.yml generated vendored Normal file
View File

@@ -0,0 +1,8 @@
coverage:
status:
project:
default:
target: 90%
patch:
default:
target: 90%

View File

@@ -318,8 +318,14 @@ func (p *WorkerPool) SubmitBefore(task func(), deadline time.Duration) {
// Stop causes this pool to stop accepting new tasks and signals all workers to exit. // Stop causes this pool to stop accepting new tasks and signals all workers to exit.
// Tasks being executed by workers will continue until completion (unless the process is terminated). // Tasks being executed by workers will continue until completion (unless the process is terminated).
// Tasks in the queue will not be executed. // Tasks in the queue will not be executed.
func (p *WorkerPool) Stop() { // This method returns a context object that is cancelled when the pool has stopped completely.
go p.stop(false) func (p *WorkerPool) Stop() context.Context {
ctx, cancel := context.WithCancel(context.Background())
go func() {
p.stop(false)
cancel()
}()
return ctx
} }
// StopAndWait causes this pool to stop accepting new tasks and then waits for all tasks in the queue // StopAndWait causes this pool to stop accepting new tasks and then waits for all tasks in the queue
@@ -371,6 +377,7 @@ func (p *WorkerPool) stop(waitForQueuedTasksToComplete bool) {
p.tasksCloseOnce.Do(func() { p.tasksCloseOnce.Do(func() {
close(p.tasks) close(p.tasks)
}) })
} }
// purge represents the work done by the purger goroutine // purge represents the work done by the purger goroutine
@@ -420,7 +427,7 @@ func (p *WorkerPool) maybeStartWorker(firstTask func()) bool {
} }
// Launch worker goroutine // Launch worker goroutine
go worker(p.context, &p.workersWaitGroup, firstTask, p.tasks, p.executeTask) go worker(p.context, &p.workersWaitGroup, firstTask, p.tasks, p.executeTask, &p.tasksWaitGroup)
return true return true
} }

View File

@@ -6,7 +6,7 @@ import (
) )
// worker represents a worker goroutine // worker represents a worker goroutine
func worker(context context.Context, waitGroup *sync.WaitGroup, firstTask func(), tasks <-chan func(), taskExecutor func(func(), bool)) { func worker(context context.Context, waitGroup *sync.WaitGroup, firstTask func(), tasks <-chan func(), taskExecutor func(func(), bool), taskWaitGroup *sync.WaitGroup) {
// If provided, execute the first task immediately, before listening to the tasks channel // If provided, execute the first task immediately, before listening to the tasks channel
if firstTask != nil { if firstTask != nil {
@@ -20,9 +20,21 @@ func worker(context context.Context, waitGroup *sync.WaitGroup, firstTask func()
for { for {
select { select {
case <-context.Done(): case <-context.Done():
// Pool context was cancelled, exit // Pool context was cancelled, empty tasks channel and exit
drainTasks(tasks, taskWaitGroup)
return return
case task, ok := <-tasks: case task, ok := <-tasks:
// Prioritize context.Done statement (https://stackoverflow.com/questions/46200343/force-priority-of-go-select-statement)
select {
case <-context.Done():
if task != nil && ok {
// We have received a task, ignore it
taskWaitGroup.Done()
}
// Pool context was cancelled, empty tasks channel and exit
drainTasks(tasks, taskWaitGroup)
return
default:
if task == nil || !ok { if task == nil || !ok {
// We have received a signal to exit // We have received a signal to exit
return return
@@ -32,4 +44,19 @@ func worker(context context.Context, waitGroup *sync.WaitGroup, firstTask func()
taskExecutor(task, false) taskExecutor(task, false)
} }
} }
}
}
// drainPendingTasks discards queued tasks and decrements the corresponding wait group
func drainTasks(tasks <-chan func(), tasksWaitGroup *sync.WaitGroup) {
for {
select {
case task, ok := <-tasks:
if task != nil && ok {
tasksWaitGroup.Done()
}
default:
return
}
}
} }

View File

@@ -1,13 +0,0 @@
# Security Policy
## Supported Versions
Security updates are applied only to the latest release.
## Reporting a Vulnerability
If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
Please disclose it at [security advisory](https://github.com/go-ole/go-ole/security/advisories/new).
This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.

View File

@@ -6,29 +6,7 @@
version: "1.3.0.{build}-alpha-{branch}" version: "1.3.0.{build}-alpha-{branch}"
os: Visual Studio 2019 os: Windows Server 2012 R2
build: off
skip_tags: true
clone_folder: c:\gopath\src\github.com\go-ole\go-ole
environment:
GOPATH: c:\gopath
GOROOT: c:\go
DOWNLOADPLATFORM: "x64"
before_test:
# - Download COM Server
- ps: Start-FileDownload "https://github.com/go-ole/test-com-server/releases/download/v1.0.2/test-com-server-${env:DOWNLOADPLATFORM}.zip"
- 7z e test-com-server-%DOWNLOADPLATFORM%.zip -oc:\gopath\src\github.com\go-ole\go-ole > NUL
- c:\gopath\src\github.com\go-ole\go-ole\build\register-assembly.bat
test_script:
- go test -v -cover ./...
# go vet has false positives on unsafe.Pointer with windows/sys. Disabling since it is recommended to use go test instead.
# - go vet ./...
branches: branches:
only: only:
@@ -37,19 +15,26 @@ branches:
- v1.1 - v1.1
- v1.0 - v1.0
matrix: skip_tags: true
allow_failures:
- environment: clone_folder: c:\gopath\src\github.com\go-ole\go-ole
GOROOT: C:\go-x86
DOWNLOADPLATFORM: "x86" environment:
- environment: GOPATH: c:\gopath
GOROOT: C:\go118 matrix:
- GOARCH: amd64
GOVERSION: 1.5
GOROOT: c:\go
DOWNLOADPLATFORM: "x64" DOWNLOADPLATFORM: "x64"
- environment:
GOROOT: C:\go118-x86
DOWNLOADPLATFORM: "x86"
install: install:
- choco install mingw
- SET PATH=c:\tools\mingw64\bin;%PATH%
# - Download COM Server
- ps: Start-FileDownload "https://github.com/go-ole/test-com-server/releases/download/v1.0.2/test-com-server-${env:DOWNLOADPLATFORM}.zip"
- 7z e test-com-server-%DOWNLOADPLATFORM%.zip -oc:\gopath\src\github.com\go-ole\go-ole > NUL
- c:\gopath\src\github.com\go-ole\go-ole\build\register-assembly.bat
# - set
- go version - go version
- go env - go env
- go get -u golang.org/x/tools/cmd/cover - go get -u golang.org/x/tools/cmd/cover
@@ -60,9 +45,10 @@ build_script:
- cd c:\gopath\src\github.com\go-ole\go-ole - cd c:\gopath\src\github.com\go-ole\go-ole
- go get -v -t ./... - go get -v -t ./...
- go build - go build
- go test -v -cover ./...
# disable automatic tests # disable automatic tests
test: on test: off
# disable deployment # disable deployment
deploy: off deploy: off

View File

@@ -11,7 +11,6 @@ import (
var ( var (
procCoInitialize = modole32.NewProc("CoInitialize") procCoInitialize = modole32.NewProc("CoInitialize")
procCoInitializeEx = modole32.NewProc("CoInitializeEx") procCoInitializeEx = modole32.NewProc("CoInitializeEx")
procCoInitializeSecurity = modole32.NewProc("CoInitializeSecurity")
procCoUninitialize = modole32.NewProc("CoUninitialize") procCoUninitialize = modole32.NewProc("CoUninitialize")
procCoCreateInstance = modole32.NewProc("CoCreateInstance") procCoCreateInstance = modole32.NewProc("CoCreateInstance")
procCoTaskMemFree = modole32.NewProc("CoTaskMemFree") procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
@@ -38,9 +37,6 @@ var (
procDispatchMessageW = moduser32.NewProc("DispatchMessageW") procDispatchMessageW = moduser32.NewProc("DispatchMessageW")
) )
// This is to enable calling COM Security initialization multiple times
var bSecurityInit bool = false
// coInitialize initializes COM library on current thread. // coInitialize initializes COM library on current thread.
// //
// MSDN documentation suggests that this function should not be called. Call // MSDN documentation suggests that this function should not be called. Call
@@ -72,35 +68,6 @@ func coInitializeEx(coinit uint32) (err error) {
return return
} }
// coInitializeSecurity: Registers security and sets the default security values
// for the process.
func coInitializeSecurity(cAuthSvc int32,
dwAuthnLevel uint32,
dwImpLevel uint32,
dwCapabilities uint32) (err error) {
// Check COM Security initialization has done previously
if !bSecurityInit {
// https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-coinitializesecurity
hr, _, _ := procCoInitializeSecurity.Call(
uintptr(0), // Allow *all* VSS writers to communicate back!
uintptr(cAuthSvc), // Default COM authentication service
uintptr(0), // Default COM authorization service
uintptr(0), // Reserved parameter
uintptr(dwAuthnLevel), // Strongest COM authentication level
uintptr(dwImpLevel), // Minimal impersonation abilities
uintptr(0), // Default COM authentication settings
uintptr(dwCapabilities), // Cloaking
uintptr(0)) // eserved parameter
if hr != 0 {
err = NewError(hr)
} else {
// COM Security initialization done make global flag true.
bSecurityInit = true
}
}
return
}
// CoInitialize initializes COM library on current thread. // CoInitialize initializes COM library on current thread.
// //
// MSDN documentation suggests that this function should not be called. Call // MSDN documentation suggests that this function should not be called. Call
@@ -129,15 +96,6 @@ func CoUninitialize() {
procCoUninitialize.Call() procCoUninitialize.Call()
} }
// CoInitializeSecurity: Registers security and sets the default security values
// for the process.
func CoInitializeSecurity(cAuthSvc int32,
dwAuthnLevel uint32,
dwImpLevel uint32,
dwCapabilities uint32) (err error) {
return coInitializeSecurity(cAuthSvc, dwAuthnLevel, dwImpLevel, dwCapabilities)
}
// CoTaskMemFree frees memory pointer. // CoTaskMemFree frees memory pointer.
func CoTaskMemFree(memptr uintptr) { func CoTaskMemFree(memptr uintptr) {
procCoTaskMemFree.Call(memptr) procCoTaskMemFree.Call(memptr)

View File

@@ -1,4 +1,3 @@
//go:build windows
// +build windows // +build windows
package ole package ole
@@ -93,7 +92,7 @@ func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}
case int8: case int8:
vargs[n] = NewVariant(VT_I1, int64(v.(int8))) vargs[n] = NewVariant(VT_I1, int64(v.(int8)))
case *int8: case *int8:
vargs[n] = NewVariant(VT_I1|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int8))))) vargs[n] = NewVariant(VT_I1|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint8)))))
case int16: case int16:
vargs[n] = NewVariant(VT_I2, int64(v.(int16))) vargs[n] = NewVariant(VT_I2, int64(v.(int16)))
case *int16: case *int16:

View File

@@ -99,7 +99,7 @@ func (v *VARIANT) Value() interface{} {
case VT_DISPATCH: case VT_DISPATCH:
return v.ToIDispatch() return v.ToIDispatch()
case VT_BOOL: case VT_BOOL:
return (v.Val & 0xffff) != 0 return v.Val != 0
} }
return nil return nil
} }

View File

@@ -1,13 +1,2 @@
# plan9stats # plan9stats
A module for retrieving statistics of Plan 9 A module for retrieving statistics of Plan 9
[![GoDev][godev-image]][godev-url]
[![Actions Status][actions-image]][actions-url]
[![Coverage Status][coveralls-image]][coveralls-url]
[godev-image]: https://pkg.go.dev/badge/github.com/lufia/plan9stats
[godev-url]: https://pkg.go.dev/github.com/lufia/plan9stats
[actions-image]: https://github.com/lufia/plan9stats/workflows/Test/badge.svg?branch=main
[actions-url]: https://github.com/lufia/plan9stats/actions?workflow=Test
[coveralls-image]: https://coveralls.io/repos/github/lufia/plan9stats/badge.svg
[coveralls-url]: https://coveralls.io/github/lufia/plan9stats

View File

@@ -178,12 +178,9 @@ func ReadCPUStats(ctx context.Context, opts ...Option) (*CPUStats, error) {
var up uint32parser var up uint32parser
pids := make([]uint32, len(names)) pids := make([]uint32, len(names))
for i, s := range names { for i, s := range names {
if s == "trace" {
continue
}
pids[i] = up.Parse(s) pids[i] = up.Parse(s)
} }
if err := up.err; err != nil { if up.err != nil {
return nil, err return nil, err
} }
sort.Slice(pids, func(i, j int) bool { sort.Slice(pids, func(i, j int) bool {

View File

@@ -1,116 +0,0 @@
package stats
import (
"bufio"
"bytes"
"context"
"os"
"path/filepath"
"strings"
)
// Storage represents /dev/sdXX/ctl.
type Storage struct {
Name string
Model string
Capacity int64
Partitions []*Partition
}
// Partition represents a part of /dev/sdXX/ctl.
type Partition struct {
Name string
Start uint64
End uint64
}
func ReadStorages(ctx context.Context, opts ...Option) ([]*Storage, error) {
cfg := newConfig(opts...)
sdctl := filepath.Join(cfg.rootdir, "/dev/sdctl")
f, err := os.Open(sdctl)
if err != nil {
return nil, err
}
defer f.Close()
var a []*Storage
scanner := bufio.NewScanner(f)
for scanner.Scan() {
fields := bytes.Split(scanner.Bytes(), delim)
if len(fields) == 0 {
continue
}
exp := string(fields[0]) + "*"
if !strings.HasPrefix(exp, "sd") {
continue
}
dir := filepath.Join(cfg.rootdir, "/dev", exp)
m, err := filepath.Glob(dir)
if err != nil {
return nil, err
}
for _, dir := range m {
s, err := readStorage(dir)
if err != nil {
return nil, err
}
a = append(a, s)
}
}
if err := scanner.Err(); err != nil {
return nil, err
}
return a, nil
}
func readStorage(dir string) (*Storage, error) {
ctl := filepath.Join(dir, "ctl")
f, err := os.Open(ctl)
if err != nil {
return nil, err
}
defer f.Close()
var s Storage
s.Name = filepath.Base(dir)
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Bytes()
switch {
case bytes.HasPrefix(line, []byte("inquiry ")):
s.Model = string(bytes.TrimSpace(line[7:]))
case bytes.HasPrefix(line, []byte("geometry ")):
fields := bytes.Split(line, delim)
if len(fields) < 3 {
continue
}
var p intParser
sec := p.ParseInt64(string(fields[1]), 10)
size := p.ParseInt64(string(fields[2]), 10)
if err := p.Err(); err != nil {
return nil, err
}
s.Capacity = sec * size
case bytes.HasPrefix(line, []byte("part ")):
fields := bytes.Split(line, delim)
if len(fields) < 4 {
continue
}
var p intParser
start := p.ParseUint64(string(fields[2]), 10)
end := p.ParseUint64(string(fields[3]), 10)
if err := p.Err(); err != nil {
return nil, err
}
s.Partitions = append(s.Partitions, &Partition{
Name: string(fields[1]),
Start: start,
End: end,
})
}
}
if err := scanner.Err(); err != nil {
return nil, err
}
return &s, nil
}

View File

@@ -109,6 +109,12 @@ func parseGauge(s string, r *Gauge) error {
return nil return nil
} }
type Storage struct {
Name string
Model string
Capacity int64
}
type Interface struct { type Interface struct {
Name string Name string
Addr string Addr string
@@ -171,7 +177,7 @@ func ReadHost(ctx context.Context, opts ...Option) (*Host, error) {
} }
h.Sysname = name h.Sysname = name
a, err := ReadStorages(ctx, opts...) a, err := readStorages(cfg.rootdir)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -197,6 +203,80 @@ func readSysname(rootdir string) (string, error) {
return string(bytes.TrimSpace(b)), nil return string(bytes.TrimSpace(b)), nil
} }
func readStorages(rootdir string) ([]*Storage, error) {
sdctl := filepath.Join(rootdir, "/dev/sdctl")
f, err := os.Open(sdctl)
if err != nil {
return nil, err
}
defer f.Close()
var a []*Storage
scanner := bufio.NewScanner(f)
for scanner.Scan() {
fields := bytes.Split(scanner.Bytes(), delim)
if len(fields) == 0 {
continue
}
exp := string(fields[0]) + "*"
if !strings.HasPrefix(exp, "sd") {
continue
}
dir := filepath.Join(rootdir, "/dev", exp)
m, err := filepath.Glob(dir)
if err != nil {
return nil, err
}
for _, dir := range m {
s, err := readStorage(dir)
if err != nil {
return nil, err
}
a = append(a, s)
}
}
if err := scanner.Err(); err != nil {
return nil, err
}
return a, nil
}
func readStorage(dir string) (*Storage, error) {
ctl := filepath.Join(dir, "ctl")
f, err := os.Open(ctl)
if err != nil {
return nil, err
}
defer f.Close()
var s Storage
s.Name = filepath.Base(dir)
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Bytes()
switch {
case bytes.HasPrefix(line, []byte("inquiry")):
s.Model = string(bytes.TrimSpace(line[7:]))
case bytes.HasPrefix(line, []byte("geometry")):
fields := bytes.Split(line, delim)
if len(fields) < 3 {
continue
}
var p intParser
sec := p.ParseInt64(string(fields[1]), 10)
size := p.ParseInt64(string(fields[2]), 10)
if err := p.Err(); err != nil {
return nil, err
}
s.Capacity = sec * size
}
}
if err := scanner.Err(); err != nil {
return nil, err
}
return &s, nil
}
type IPStats struct { type IPStats struct {
ID int // number of interface in ipifc dir ID int // number of interface in ipifc dir
Device string // associated physical device Device string // associated physical device

View File

@@ -26,15 +26,6 @@ func (p *intParser) ParseInt64(s string, base int) int64 {
return n return n
} }
func (p *intParser) ParseUint64(s string, base int) uint64 {
if p.err != nil {
return 0
}
var n uint64
n, p.err = strconv.ParseUint(s, base, 64)
return n
}
func (p *intParser) Err() error { func (p *intParser) Err() error {
return p.err return p.err
} }

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix // +build aix
package perfstat package perfstat

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix // +build aix
package perfstat package perfstat
@@ -21,13 +20,6 @@ import (
"unsafe" "unsafe"
) )
var old_cpu_total_stat *C.perfstat_cpu_total_t
func init() {
old_cpu_total_stat = (*C.perfstat_cpu_total_t)(C.malloc(C.sizeof_perfstat_cpu_total_t))
C.perfstat_cpu_total(nil, old_cpu_total_stat, C.sizeof_perfstat_cpu_total_t, 1)
}
func CpuStat() ([]CPU, error) { func CpuStat() ([]CPU, error) {
var cpustat *C.perfstat_cpu_t var cpustat *C.perfstat_cpu_t
var cpu C.perfstat_id_t var cpu C.perfstat_id_t
@@ -104,35 +96,3 @@ func CpuUtilStat(intvl time.Duration) (*CPUUtil, error) {
u := perfstatcpuutil2cpuutil(cpuutil) u := perfstatcpuutil2cpuutil(cpuutil)
return &u, nil return &u, nil
} }
func CpuUtilTotalStat() (*CPUUtil, error) {
var cpuutil *C.perfstat_cpu_util_t
var new_cpu_total_stat *C.perfstat_cpu_total_t
var data C.perfstat_rawdata_t
new_cpu_total_stat = (*C.perfstat_cpu_total_t)(C.malloc(C.sizeof_perfstat_cpu_total_t))
cpuutil = (*C.perfstat_cpu_util_t)(C.malloc(C.sizeof_perfstat_cpu_util_t))
defer C.free(unsafe.Pointer(cpuutil))
r := C.perfstat_cpu_total(nil, new_cpu_total_stat, C.sizeof_perfstat_cpu_total_t, 1)
if r <= 0 {
C.free(unsafe.Pointer(new_cpu_total_stat))
return nil, fmt.Errorf("error perfstat_cpu_total()")
}
data._type = C.UTIL_CPU_TOTAL
data.curstat = unsafe.Pointer(new_cpu_total_stat)
data.prevstat = unsafe.Pointer(old_cpu_total_stat)
data.sizeof_data = C.sizeof_perfstat_cpu_total_t
data.cur_elems = 1
data.prev_elems = 1
r = C.perfstat_cpu_util(&data, cpuutil, C.sizeof_perfstat_cpu_util_t, 1)
C.free(unsafe.Pointer(old_cpu_total_stat))
old_cpu_total_stat = new_cpu_total_stat
if r <= 0 {
return nil, fmt.Errorf("error perfstat_cpu_util()")
}
u := perfstatcpuutil2cpuutil(cpuutil)
return &u, nil
}

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix // +build aix
package perfstat package perfstat

View File

@@ -1,4 +1,3 @@
//go:build !aix
// +build !aix // +build !aix
// Copyright 2020 Power-Devops.com. All rights reserved. // Copyright 2020 Power-Devops.com. All rights reserved.
@@ -37,24 +36,24 @@ func DisableLVMStat() {}
// CpuStat() returns array of CPU structures with information about // CpuStat() returns array of CPU structures with information about
// logical CPUs on the system. // logical CPUs on the system.
// IBM documentation: // IBM documentation:
// - https://www.ibm.com/support/knowledgecenter/ssw_aix_72/performancetools/idprftools_perfstat_int_cpu.html // * https://www.ibm.com/support/knowledgecenter/ssw_aix_72/performancetools/idprftools_perfstat_int_cpu.html
// - https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/p_bostechref/perfstat_cpu.html // * https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/p_bostechref/perfstat_cpu.html
func CpuStat() ([]CPU, error) { func CpuStat() ([]CPU, error) {
return nil, fmt.Errorf("not implemented") return nil, fmt.Errorf("not implemented")
} }
// CpuTotalStat() returns general information about CPUs on the system. // CpuTotalStat() returns general information about CPUs on the system.
// IBM documentation: // IBM documentation:
// - https://www.ibm.com/support/knowledgecenter/ssw_aix_72/performancetools/idprftools_perfstat_glob_cpu.html // * https://www.ibm.com/support/knowledgecenter/ssw_aix_72/performancetools/idprftools_perfstat_glob_cpu.html
// - https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/p_bostechref/perfstat_cputot.html // * https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/p_bostechref/perfstat_cputot.html
func CpuTotalStat() (*CPUTotal, error) { func CpuTotalStat() (*CPUTotal, error) {
return nil, fmt.Errorf("not implemented") return nil, fmt.Errorf("not implemented")
} }
// CpuUtilStat() calculates CPU utilization. // CpuUtilStat() calculates CPU utilization.
// IBM documentation: // IBM documentation:
// - https://www.ibm.com/support/knowledgecenter/ssw_aix_72/performancetools/idprftools_perfstat_cpu_util.html // * https://www.ibm.com/support/knowledgecenter/ssw_aix_72/performancetools/idprftools_perfstat_cpu_util.html
// - https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/p_bostechref/perfstat_cpu_util.html // * https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/p_bostechref/perfstat_cpu_util.html
func CpuUtilStat(intvl time.Duration) (*CPUUtil, error) { func CpuUtilStat(intvl time.Duration) (*CPUUtil, error) {
return nil, fmt.Errorf("not implemented") return nil, fmt.Errorf("not implemented")
} }

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix // +build aix
package perfstat package perfstat

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix // +build aix
package perfstat package perfstat
@@ -8,7 +7,6 @@ package perfstat
#include <libperfstat.h> #include <libperfstat.h>
#include <sys/proc.h> #include <sys/proc.h>
#include <sys/dr.h>
#include "c_helpers.h" #include "c_helpers.h"
*/ */
@@ -756,7 +754,7 @@ func fsinfo2filesystem(n *C.struct_fsinfo) FileSystem {
i.Device = C.GoString(n.devname) i.Device = C.GoString(n.devname)
i.MountPoint = C.GoString(n.fsname) i.MountPoint = C.GoString(n.fsname)
i.FSType = int(n.fstype) i.FSType = int(n.fstype)
i.Flags = uint(n.flags) i.Flags = int(n.flags)
i.TotalBlocks = int64(n.totalblks) i.TotalBlocks = int64(n.totalblks)
i.FreeBlocks = int64(n.freeblks) i.FreeBlocks = int64(n.freeblks)
i.TotalInodes = int64(n.totalinodes) i.TotalInodes = int64(n.totalinodes)
@@ -764,56 +762,3 @@ func fsinfo2filesystem(n *C.struct_fsinfo) FileSystem {
return i return i
} }
func lparinfo2partinfo(n C.lpar_info_format2_t) PartitionInfo {
var i PartitionInfo
i.Version = int(n.version)
i.OnlineMemory = uint64(n.online_memory)
i.TotalDispatchTime = uint64(n.tot_dispatch_time)
i.PoolIdleTime = uint64(n.pool_idle_time)
i.DispatchLatency = uint64(n.dispatch_latency)
i.LparFlags = uint(n.lpar_flags)
i.PCpusInSys = uint(n.pcpus_in_sys)
i.OnlineVCpus = uint(n.online_vcpus)
i.OnlineLCpus = uint(n.online_lcpus)
i.PCpusInPool = uint(n.pcpus_in_pool)
i.UnallocCapacity = uint(n.unalloc_capacity)
i.EntitledCapacity = uint(n.entitled_capacity)
i.VariableWeight = uint(n.variable_weight)
i.UnallocWeight = uint(n.unalloc_weight)
i.MinReqVCpuCapacity = uint(n.min_req_vcpu_capacity)
i.GroupId = uint8(n.group_id)
i.PoolId = uint8(n.pool_id)
i.ShCpusInSys = uint(n.shcpus_in_sys)
i.MaxPoolCapacity = uint(n.max_pool_capacity)
i.EntitledPoolCapacity = uint(n.entitled_pool_capacity)
i.PoolMaxTime = uint64(n.pool_max_time)
i.PoolBusyTime = uint64(n.pool_busy_time)
i.PoolScaledBusyTime = uint64(n.pool_scaled_busy_time)
i.ShCpuTotalTime = uint64(n.shcpu_tot_time)
i.ShCpuBusyTime = uint64(n.shcpu_busy_time)
i.ShCpuScaledBusyTime = uint64(n.shcpu_scaled_busy_time)
i.EntMemCapacity = uint64(n.ent_mem_capacity)
i.PhysMem = uint64(n.phys_mem)
i.VrmPoolPhysMem = uint64(n.vrm_pool_physmem)
i.HypPageSize = uint(n.hyp_pagesize)
i.VrmPoolId = int(n.vrm_pool_id)
i.VrmGroupId = int(n.vrm_group_id)
i.VarMemWeight = int(n.var_mem_weight)
i.UnallocVarMemWeight = int(n.unalloc_var_mem_weight)
i.UnallocEntMemCapacity = uint64(n.unalloc_ent_mem_capacity)
i.TrueOnlineMemory = uint64(n.true_online_memory)
i.AmeOnlineMemory = uint64(n.ame_online_memory)
i.AmeType = uint8(n.ame_type)
i.SpecExecMode = uint8(n.spec_exec_mode)
i.AmeFactor = uint(n.ame_factor)
i.EmPartMajorCode = uint(n.em_part_major_code)
i.EmPartMinorCode = uint(n.em_part_minor_code)
i.BytesCoalesced = uint64(n.bytes_coalesced)
i.BytesCoalescedMemPool = uint64(n.bytes_coalesced_mempool)
i.PurrCoalescing = uint64(n.purr_coalescing)
i.SpurrCoalescing = uint64(n.spurr_coalescing)
return i
}

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix // +build aix
package perfstat package perfstat
@@ -7,13 +6,11 @@ package perfstat
#cgo LDFLAGS: -lperfstat #cgo LDFLAGS: -lperfstat
#include <libperfstat.h> #include <libperfstat.h>
#include <sys/dr.h>
*/ */
import "C" import "C"
import ( import (
"fmt" "fmt"
"unsafe"
) )
func PartitionStat() (*PartitionConfig, error) { func PartitionStat() (*PartitionConfig, error) {
@@ -27,14 +24,3 @@ func PartitionStat() (*PartitionConfig, error) {
return &p, nil return &p, nil
} }
func LparInfo() (*PartitionInfo, error) {
var pinfo C.lpar_info_format2_t
rc := C.lpar_get_info(C.LPAR_INFO_FORMAT2, unsafe.Pointer(&pinfo), C.sizeof_lpar_info_format2_t)
if rc != 0 {
return nil, fmt.Errorf("lpar_get_info() error")
}
p := lparinfo2partinfo(pinfo)
return &p, nil
}

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix // +build aix
package perfstat package perfstat

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix // +build aix
package perfstat package perfstat

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix // +build aix
package perfstat package perfstat

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix // +build aix
package perfstat package perfstat

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix // +build aix
package perfstat package perfstat

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix // +build aix
package perfstat package perfstat
@@ -71,7 +70,6 @@ const (
SC_TM_VER = 59 /* Transaction Memory version, 0 - not capable */ SC_TM_VER = 59 /* Transaction Memory version, 0 - not capable */
SC_NX_CAP = 60 /* NX GZIP capable */ SC_NX_CAP = 60 /* NX GZIP capable */
SC_PKS_STATE = 61 /* Platform KeyStore */ SC_PKS_STATE = 61 /* Platform KeyStore */
SC_MMA_VER = 62
) )
/* kernel attributes */ /* kernel attributes */
@@ -121,7 +119,6 @@ const (
IMPL_POWER7 = 0x8000 /* 7 class CPU */ IMPL_POWER7 = 0x8000 /* 7 class CPU */
IMPL_POWER8 = 0x10000 /* 8 class CPU */ IMPL_POWER8 = 0x10000 /* 8 class CPU */
IMPL_POWER9 = 0x20000 /* 9 class CPU */ IMPL_POWER9 = 0x20000 /* 9 class CPU */
IMPL_POWER10 = 0x20000 /* 10 class CPU */
) )
// Values for implementation field for IA64 Architectures // Values for implementation field for IA64 Architectures
@@ -154,13 +151,11 @@ const (
PV_7 = 0x200000 /* Power PC 7 */ PV_7 = 0x200000 /* Power PC 7 */
PV_8 = 0x300000 /* Power PC 8 */ PV_8 = 0x300000 /* Power PC 8 */
PV_9 = 0x400000 /* Power PC 9 */ PV_9 = 0x400000 /* Power PC 9 */
PV_10 = 0x500000 /* Power PC 10 */
PV_5_Compat = 0x0F8000 /* Power PC 5 */ PV_5_Compat = 0x0F8000 /* Power PC 5 */
PV_6_Compat = 0x108000 /* Power PC 6 */ PV_6_Compat = 0x108000 /* Power PC 6 */
PV_7_Compat = 0x208000 /* Power PC 7 */ PV_7_Compat = 0x208000 /* Power PC 7 */
PV_8_Compat = 0x308000 /* Power PC 8 */ PV_8_Compat = 0x308000 /* Power PC 8 */
PV_9_Compat = 0x408000 /* Power PC 9 */ PV_9_Compat = 0x408000 /* Power PC 9 */
PV_10_Compat = 0x508000 /* Power PC 10 */
PV_RESERVED_2 = 0x0A0000 /* source compatability */ PV_RESERVED_2 = 0x0A0000 /* source compatability */
PV_RESERVED_3 = 0x0B0000 /* source compatability */ PV_RESERVED_3 = 0x0B0000 /* source compatability */
PV_RS2 = 0x040000 /* Power RS2 */ PV_RS2 = 0x040000 /* Power RS2 */
@@ -199,8 +194,6 @@ const (
PPI8_1 = 0x4B PPI8_1 = 0x4B
PPI8_2 = 0x4D PPI8_2 = 0x4D
PPI9 = 0x4E PPI9 = 0x4E
PPI9_1 = 0x4E
PPI10_1 = 0x80
) )
// Macros for kernel attributes // Macros for kernel attributes
@@ -298,32 +291,14 @@ func GetCPUImplementation() string {
return "POWER8" return "POWER8"
case impl&IMPL_POWER9 != 0: case impl&IMPL_POWER9 != 0:
return "POWER9" return "POWER9"
case impl&IMPL_POWER10 != 0:
return "Power10"
default: default:
return "Unknown" return "Unknown"
} }
} }
func POWER10OrNewer() bool {
impl := unix.Getsystemcfg(SC_IMPL)
if impl&IMPL_POWER10 != 0 {
return true
}
return false
}
func POWER10() bool {
impl := unix.Getsystemcfg(SC_IMPL)
if impl&IMPL_POWER10 != 0 {
return true
}
return false
}
func POWER9OrNewer() bool { func POWER9OrNewer() bool {
impl := unix.Getsystemcfg(SC_IMPL) impl := unix.Getsystemcfg(SC_IMPL)
if impl&IMPL_POWER10 != 0 || impl&IMPL_POWER9 != 0 { if impl&IMPL_POWER9 != 0 {
return true return true
} }
return false return false
@@ -339,7 +314,7 @@ func POWER9() bool {
func POWER8OrNewer() bool { func POWER8OrNewer() bool {
impl := unix.Getsystemcfg(SC_IMPL) impl := unix.Getsystemcfg(SC_IMPL)
if impl&IMPL_POWER10 != 0 || impl&IMPL_POWER9 != 0 || impl&IMPL_POWER8 != 0 { if impl&IMPL_POWER9 != 0 || impl&IMPL_POWER8 != 0 {
return true return true
} }
return false return false
@@ -355,7 +330,7 @@ func POWER8() bool {
func POWER7OrNewer() bool { func POWER7OrNewer() bool {
impl := unix.Getsystemcfg(SC_IMPL) impl := unix.Getsystemcfg(SC_IMPL)
if impl&IMPL_POWER10 != 0 || impl&IMPL_POWER9 != 0 || impl&IMPL_POWER8 != 0 || impl&IMPL_POWER7 != 0 { if impl&IMPL_POWER9 != 0 || impl&IMPL_POWER8 != 0 || impl&IMPL_POWER7 != 0 {
return true return true
} }
return false return false
@@ -444,8 +419,6 @@ func PksEnabled() bool {
func CPUMode() string { func CPUMode() string {
impl := unix.Getsystemcfg(SC_VERS) impl := unix.Getsystemcfg(SC_VERS)
switch impl { switch impl {
case PV_10, PV_10_Compat:
return "Power10"
case PV_9, PV_9_Compat: case PV_9, PV_9_Compat:
return "POWER9" return "POWER9"
case PV_8, PV_8_Compat: case PV_8, PV_8_Compat:

View File

@@ -29,8 +29,8 @@ type DiskTotal struct {
// Disk Adapter Types // Disk Adapter Types
const ( const (
DA_SCSI = 0 /* 0 ==> SCSI, SAS, other legacy adapter types */ DA_SCSI = 0 /* 0 ==> SCSI, SAS, other legacy adapter types */
DA_VSCSI = 1 /* 1 ==> Virtual SCSI/SAS Adapter */ DA_VSCSI /* 1 ==> Virtual SCSI/SAS Adapter */
DA_FCA = 2 /* 2 ==> Fiber Channel Adapter */ DA_FCA /* 2 ==> Fiber Channel Adapter */
) )
type DiskAdapter struct { type DiskAdapter struct {

View File

@@ -8,7 +8,7 @@ type FileSystem struct {
Device string /* name of the mounted device */ Device string /* name of the mounted device */
MountPoint string /* where the device is mounted */ MountPoint string /* where the device is mounted */
FSType int /* File system type, see the constants below */ FSType int /* File system type, see the constants below */
Flags uint /* Flags of the file system */ Flags int /* Flags of the file system */
TotalBlocks int64 /* number of 512 bytes blocks in the filesystem */ TotalBlocks int64 /* number of 512 bytes blocks in the filesystem */
FreeBlocks int64 /* number of free 512 bytes block in the filesystem */ FreeBlocks int64 /* number of free 512 bytes block in the filesystem */
TotalInodes int64 /* total number of inodes in the filesystem */ TotalInodes int64 /* total number of inodes in the filesystem */

View File

@@ -66,64 +66,3 @@ type PartitionConfig struct {
TargetMemExpSize int64 /* Expanded Memory Size in MB */ TargetMemExpSize int64 /* Expanded Memory Size in MB */
SubProcessorMode int32 /* Split core mode, its value can be 0,1,2 or 4. 0 for unsupported, 1 for capable but not enabled, 2 or 4 for enabled*/ SubProcessorMode int32 /* Split core mode, its value can be 0,1,2 or 4. 0 for unsupported, 1 for capable but not enabled, 2 or 4 for enabled*/
} }
const (
AME_TYPE_V1 = 0x1
AME_TYPE_V2 = 0x2
LPAR_INFO_CAPPED = 0x01 /* Parition Capped */
LPAR_INFO_AUTH_PIC = 0x02 /* Authority granted for poolidle*/
LPAR_INFO_SMT_ENABLED = 0x04 /* SMT Enabled */
LPAR_INFO_WPAR_ACTIVE = 0x08 /* Process Running Within a WPAR */
LPAR_INFO_EXTENDED = 0x10 /* Extended shared processor pool information */
LPAR_INFO_AME_ENABLED = 0x20 /* Active Mem. Expansion (AME) enabled*/
LPAR_INFO_SEM_ENABLED = 0x40 /* Speculative Execution Mode enabled */
)
type PartitionInfo struct {
Version int /* version for this structure */
OnlineMemory uint64 /* MB of currently online memory */
TotalDispatchTime uint64 /* Total lpar dispatch time in nsecs */
PoolIdleTime uint64 /* Idle time of shared CPU pool nsecs*/
DispatchLatency uint64 /* Max latency inbetween dispatches of this LPAR on physCPUS in nsecs */
LparFlags uint /* LPAR flags */
PCpusInSys uint /* # of active licensed physical CPUs in system */
OnlineVCpus uint /* # of current online virtual CPUs */
OnlineLCpus uint /* # of current online logical CPUs */
PCpusInPool uint /* # physical CPUs in shared pool */
UnallocCapacity uint /* Unallocated Capacity available in shared pool */
EntitledCapacity uint /* Entitled Processor Capacity for this partition */
VariableWeight uint /* Variable Processor Capacity Weight */
UnallocWeight uint /* Unallocated Variable Weight available for this partition */
MinReqVCpuCapacity uint /* OS minimum required virtual processor capacity. */
GroupId uint8 /* ID of a LPAR group/aggregation */
PoolId uint8 /* ID of a shared pool */
ShCpusInSys uint /* # of physical processors allocated for shared processor use */
MaxPoolCapacity uint /* Maximum processor capacity of partition's pool */
EntitledPoolCapacity uint /* Entitled processor capacity of partition's pool */
PoolMaxTime uint64 /* Summation of maximum time that could be consumed by the pool, in nanoseconds */
PoolBusyTime uint64 /* Summation of busy time accumulated across all partitions in the pool, in nanoseconds */
PoolScaledBusyTime uint64 /* Scaled summation of busy time accumulated across all partitions in the pool, in nanoseconds */
ShCpuTotalTime uint64 /* Summation of total time across all physical processors allocated for shared processor use, in nanoseconds */
ShCpuBusyTime uint64 /* Summation of busy time accumulated across all shared processor partitions, in nanoseconds */
ShCpuScaledBusyTime uint64 /* Scaled summation of busy time accumulated across all shared processor partitions, in nanoseconds */
EntMemCapacity uint64 /* Partition's current entitlement memory capacity setting */
PhysMem uint64 /* Amount of physical memory, in bytes, currently backing the partition's logical memory */
VrmPoolPhysMem uint64 /* Total amount of physical memory in the VRM pool */
HypPageSize uint /* Page size hypervisor is using to virtualize partition's memory */
VrmPoolId int /* ID of VRM pool */
VrmGroupId int /* eWLM VRM group to which partition belongs */
VarMemWeight int /* Partition's current variable memory capacity weighting setting */
UnallocVarMemWeight int /* Amount of unallocated variable memory capacity weight available to LPAR's group */
UnallocEntMemCapacity uint64 /* Amount of unallocated I/O memory entitlement available to LPAR's group */
TrueOnlineMemory uint64 /* true MB of currently online memory */
AmeOnlineMemory uint64 /* AME MB of currently online memory */
AmeType uint8
SpecExecMode uint8 /* Speculative Execution Mode */
AmeFactor uint /* memory expansion factor for LPAR */
EmPartMajorCode uint /* Major and minor codes for our */
EmPartMinorCode uint /* current energy management mode */
BytesCoalesced uint64 /* The number of bytes of the calling partition.s logical real memory coalesced because they contained duplicated data */
BytesCoalescedMemPool uint64 /* If the calling partition is authorized to see pool wide statistics then the number of bytes of logical real memory coalesced because they contained duplicated data in the calling partition.s memory pool else set to zero.*/
PurrCoalescing uint64 /* If the calling partition is authorized to see pool wide statistics then PURR cycles consumed to coalesce data else set to zero.*/
SpurrCoalescing uint64 /* If the calling partition is authorized to see pool wide statistics then SPURR cycles consumed to coalesce data else set to zero.*/
}

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix // +build aix
package perfstat package perfstat

View File

@@ -12,8 +12,57 @@ import (
) )
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
var ret []TimesStat
if percpu { if percpu {
per_out, err := invoke.CommandWithContext(ctx, "sar", "-u", "-P", "ALL", "10", "1")
if err != nil {
return nil, err
}
lines := strings.Split(string(per_out), "\n")
if len(lines) < 6 {
return []TimesStat{}, common.ErrNotImplementedError return []TimesStat{}, common.ErrNotImplementedError
}
hp := strings.Fields(lines[5]) // headers
for l := 6; l < len(lines)-1; l++ {
ct := &TimesStat{}
v := strings.Fields(lines[l]) // values
for i, header := range hp {
// We're done in any of these use cases
if i >= len(v) || v[0] == "-" {
break
}
// Position variable for v
pos := i
// There is a missing field at the beginning of all but the first line
// so adjust the position
if l > 6 {
pos = i - 1
}
// We don't want invalid positions
if pos < 0 {
continue
}
if t, err := strconv.ParseFloat(v[pos], 64); err == nil {
switch header {
case `cpu`:
ct.CPU = strconv.FormatFloat(t, 'f', -1, 64)
case `%usr`:
ct.User = t
case `%sys`:
ct.System = t
case `%wio`:
ct.Iowait = t
case `%idle`:
ct.Idle = t
}
}
}
// Valid CPU data, so append it
ret = append(ret, *ct)
}
} else { } else {
out, err := invoke.CommandWithContext(ctx, "sar", "-u", "10", "1") out, err := invoke.CommandWithContext(ctx, "sar", "-u", "10", "1")
if err != nil { if err != nil {
@@ -24,26 +73,28 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
return []TimesStat{}, common.ErrNotImplementedError return []TimesStat{}, common.ErrNotImplementedError
} }
ret := TimesStat{CPU: "cpu-total"} ct := &TimesStat{CPU: "cpu-total"}
h := strings.Fields(lines[len(lines)-3]) // headers h := strings.Fields(lines[len(lines)-3]) // headers
v := strings.Fields(lines[len(lines)-2]) // values v := strings.Fields(lines[len(lines)-2]) // values
for i, header := range h { for i, header := range h {
if t, err := strconv.ParseFloat(v[i], 64); err == nil { if t, err := strconv.ParseFloat(v[i], 64); err == nil {
switch header { switch header {
case `%usr`: case `%usr`:
ret.User = t ct.User = t
case `%sys`: case `%sys`:
ret.System = t ct.System = t
case `%wio`: case `%wio`:
ret.Iowait = t ct.Iowait = t
case `%idle`: case `%idle`:
ret.Idle = t ct.Idle = t
} }
} }
} }
return []TimesStat{ret}, nil ret = append(ret, *ct)
} }
return ret, nil
} }
func InfoWithContext(ctx context.Context) ([]InfoStat, error) { func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
@@ -78,6 +129,20 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
} }
} }
break break
} else if strings.HasPrefix(line, "System Model:") {
p := strings.Split(string(line), ":")
if p != nil {
ret.VendorID = strings.TrimSpace(p[1])
}
} else if strings.HasPrefix(line, "Processor Type:") {
p := strings.Split(string(line), ":")
if p != nil {
c := strings.Split(string(p[1]), "_")
if c != nil {
ret.Family = strings.TrimSpace(c[0])
ret.Model = strings.TrimSpace(c[1])
}
}
} }
} }
return []InfoStat{ret}, nil return []InfoStat{ret}, nil

View File

@@ -6,7 +6,7 @@ import (
) )
// Sleep awaits for provided interval. // Sleep awaits for provided interval.
// Can be interrupted by context cancelation. // Can be interrupted by context cancellation.
func Sleep(ctx context.Context, interval time.Duration) error { func Sleep(ctx context.Context, interval time.Duration) error {
timer := time.NewTimer(interval) timer := time.NewTimer(interval)
select { select {

View File

@@ -12,7 +12,7 @@ import (
) )
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
vmem, swap, err := callSVMon(ctx) vmem, swap, err := callSVMon(ctx, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -25,7 +25,7 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
} }
func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
_, swap, err := callSVMon(ctx) _, swap, err := callSVMon(ctx, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -35,7 +35,7 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
return swap, nil return swap, nil
} }
func callSVMon(ctx context.Context) (*VirtualMemoryStat, *SwapMemoryStat, error) { func callSVMon(ctx context.Context, virt bool) (*VirtualMemoryStat, *SwapMemoryStat, error) {
out, err := invoke.CommandWithContext(ctx, "svmon", "-G") out, err := invoke.CommandWithContext(ctx, "svmon", "-G")
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@@ -45,7 +45,7 @@ func callSVMon(ctx context.Context) (*VirtualMemoryStat, *SwapMemoryStat, error)
vmem := &VirtualMemoryStat{} vmem := &VirtualMemoryStat{}
swap := &SwapMemoryStat{} swap := &SwapMemoryStat{}
for _, line := range strings.Split(string(out), "\n") { for _, line := range strings.Split(string(out), "\n") {
if strings.HasPrefix(line, "memory") { if virt && strings.HasPrefix(line, "memory") {
p := strings.Fields(line) p := strings.Fields(line)
if len(p) > 2 { if len(p) > 2 {
if t, err := strconv.ParseUint(p[1], 10, 64); err == nil { if t, err := strconv.ParseUint(p[1], 10, 64); err == nil {

View File

@@ -471,7 +471,7 @@ func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, p
} }
} }
if err != nil { if err != nil {
return nil, fmt.Errorf("cound not get pid(s), %d: %w", pid, err) return nil, fmt.Errorf("could not get pid(s), %d: %w", pid, err)
} }
return statsFromInodesWithContext(ctx, root, pid, tmap, inodes, skipUids) return statsFromInodesWithContext(ctx, root, pid, tmap, inodes, skipUids)
} }

View File

@@ -23,9 +23,9 @@ func ParseNetstat(output string, mode string,
exists := make([]string, 0, len(lines)-1) exists := make([]string, 0, len(lines)-1)
columns := 6 columns := 9
if mode == "ind" { if mode == "inb" {
columns = 10 columns = 6
} }
for _, line := range lines { for _, line := range lines {
values := strings.Fields(line) values := strings.Fields(line)
@@ -48,18 +48,23 @@ func ParseNetstat(output string, mode string,
parsed := make([]uint64, 0, 8) parsed := make([]uint64, 0, 8)
var vv []string var vv []string
if mode == "inb" { switch mode {
case "inb":
vv = []string{ vv = []string{
values[base+3], // BytesRecv values[base+3], // BytesRecv
values[base+4], // BytesSent values[base+4], // BytesSent
} }
} else { case "ind":
vv = []string{ vv = []string{
values[base+3], // Ipkts values[base+3], // Ipkts
values[base+4], // Ierrs values[base+4], // Idrop
values[base+5], // Opkts values[base+5], // Opkts
values[base+6], // Odrops
}
case "ine":
vv = []string{
values[base+4], // Ierrs
values[base+6], // Oerrs values[base+6], // Oerrs
values[base+8], // Drops
} }
} }
for _, target := range vv { for _, target := range vv {
@@ -80,16 +85,19 @@ func ParseNetstat(output string, mode string,
if !present { if !present {
n = IOCountersStat{Name: values[0]} n = IOCountersStat{Name: values[0]}
} }
if mode == "inb" {
switch mode {
case "inb":
n.BytesRecv = parsed[0] n.BytesRecv = parsed[0]
n.BytesSent = parsed[1] n.BytesSent = parsed[1]
} else { case "ind":
n.PacketsRecv = parsed[0] n.PacketsRecv = parsed[0]
n.Errin = parsed[1] n.Dropin = parsed[1]
n.PacketsSent = parsed[2] n.PacketsSent = parsed[2]
n.Errout = parsed[3] n.Dropout = parsed[3]
n.Dropin = parsed[4] case "ine":
n.Dropout = parsed[4] n.Errin = parsed[0]
n.Errout = parsed[1]
} }
iocs[n.Name] = n iocs[n.Name] = n
@@ -114,6 +122,10 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat,
if err != nil { if err != nil {
return nil, err return nil, err
} }
out3, err := invoke.CommandWithContext(ctx, netstat, "-ine")
if err != nil {
return nil, err
}
iocs := make(map[string]IOCountersStat) iocs := make(map[string]IOCountersStat)
lines := strings.Split(string(out), "\n") lines := strings.Split(string(out), "\n")
@@ -127,6 +139,10 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat,
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = ParseNetstat(string(out3), "ine", iocs)
if err != nil {
return nil, err
}
for _, ioc := range iocs { for _, ioc := range iocs {
ret = append(ret, ioc) ret = append(ret, ioc)

View File

@@ -24,14 +24,21 @@ func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
} }
txtFound := 0 txtFound := 0
lines := strings.Split(string(out), "\n") lines := strings.Split(string(out), "\n")
fallback := ""
for i := 1; i < len(lines); i++ { for i := 1; i < len(lines); i++ {
if lines[i] == "ftxt" { if lines[i] == "ftxt" {
txtFound++ txtFound++
if txtFound == 1 {
fallback = lines[i-1][1:]
}
if txtFound == 2 { if txtFound == 2 {
return lines[i-1][1:], nil return lines[i-1][1:], nil
} }
} }
} }
if fallback != "" {
return fallback, nil
}
return "", fmt.Errorf("missing txt data returned by lsof") return "", fmt.Errorf("missing txt data returned by lsof")
} }

View File

@@ -68,7 +68,12 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
} }
func (p *Process) CwdWithContext(ctx context.Context) (string, error) { func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError mib := []int32{CTLKern, KernProcCwd, p.Pid}
buf, _, err := common.CallSyscall(mib)
if err != nil {
return "", err
}
return common.ByteToString(buf), nil
} }
func (p *Process) ExeWithContext(ctx context.Context) (string, error) { func (p *Process) ExeWithContext(ctx context.Context) (string, error) {

View File

@@ -14,6 +14,7 @@ const (
KernProcProc = 8 KernProcProc = 8
KernProcPathname = 12 KernProcPathname = 12
KernProcArgs = 55 KernProcArgs = 55
KernProcCwd = 78
KernProcArgv = 1 KernProcArgv = 1
KernProcEnv = 3 KernProcEnv = 3
) )

View File

@@ -11,6 +11,7 @@ const (
KernProcProc = 8 KernProcProc = 8
KernProcPathname = 12 KernProcPathname = 12
KernProcArgs = 55 KernProcArgs = 55
KernProcCwd = 78
KernProcArgv = 1 KernProcArgv = 1
KernProcEnv = 3 KernProcEnv = 3
) )

View File

@@ -14,6 +14,7 @@ const (
KernProcProc = 8 KernProcProc = 8
KernProcPathname = 12 KernProcPathname = 12
KernProcArgs = 55 KernProcArgs = 55
KernProcCwd = 78
KernProcArgv = 1 KernProcArgv = 1
KernProcEnv = 3 KernProcEnv = 3
) )

View File

@@ -14,6 +14,7 @@ const (
KernProcProc = 8 KernProcProc = 8
KernProcPathname = 12 KernProcPathname = 12
KernProcArgs = 55 KernProcArgs = 55
KernProcCwd = 78
KernProcArgv = 1 KernProcArgv = 1
KernProcEnv = 3 KernProcEnv = 3
) )

View File

@@ -14,6 +14,7 @@ const (
KernProcProc = 8 KernProcProc = 8
KernProcPathname = 12 KernProcPathname = 12
KernProcArgs = 55 KernProcArgs = 55
KernProcCwd = 78
KernProcArgv = 1 KernProcArgv = 1
KernProcEnv = 3 KernProcEnv = 3
) )

View File

@@ -1,6 +1,6 @@
env: env:
CIRRUS_CLONE_DEPTH: 1 CIRRUS_CLONE_DEPTH: 1
GO_VERSION: go1.21.3 GO_VERSION: go1.20
freebsd_12_task: freebsd_12_task:
freebsd_instance: freebsd_instance:

View File

@@ -6,6 +6,7 @@ package sysconf
import ( import (
"bufio" "bufio"
"io/ioutil"
"os" "os"
"runtime" "runtime"
"strconv" "strconv"
@@ -25,7 +26,7 @@ const (
) )
func readProcFsInt64(path string, fallback int64) int64 { func readProcFsInt64(path string, fallback int64) int64 {
data, err := os.ReadFile(path) data, err := ioutil.ReadFile(path)
if err != nil { if err != nil {
return fallback return fallback
} }
@@ -85,17 +86,11 @@ func getNprocsProcStat() (int64, error) {
s := bufio.NewScanner(f) s := bufio.NewScanner(f)
for s.Scan() { for s.Scan() {
if line := strings.TrimSpace(s.Text()); strings.HasPrefix(line, "cpu") { if line := strings.TrimSpace(s.Text()); strings.HasPrefix(line, "cpu") {
cpu, _, found := strings.Cut(line, " ") l := strings.SplitN(line, " ", 2)
if found { _, err := strconv.ParseInt(l[0][3:], 10, 64)
// skip first line with accumulated values
if cpu == "cpu" {
continue
}
_, err := strconv.ParseInt(cpu[len("cpu"):], 10, 64)
if err == nil { if err == nil {
count++ count++
} }
}
} else { } else {
// The current format of /proc/stat has all the // The current format of /proc/stat has all the
// cpu* lines at the beginning. Assume this // cpu* lines at the beginning. Assume this
@@ -103,9 +98,6 @@ func getNprocsProcStat() (int64, error) {
break break
} }
} }
if err := s.Err(); err != nil {
return -1, err
}
return count, nil return count, nil
} }

View File

@@ -25,10 +25,10 @@ const (
_POSIX2_UPE = -1 _POSIX2_UPE = -1
) )
var clktck struct { var (
sync.Once clktck int64
v int64 clktckOnce sync.Once
} )
func sysconfPOSIX(name int) (int64, error) { func sysconfPOSIX(name int) (int64, error) {
// NetBSD does not define all _POSIX_* values used in sysconf_posix.go // NetBSD does not define all _POSIX_* values used in sysconf_posix.go
@@ -42,6 +42,7 @@ func sysconf(name int) (int64, error) {
// Duplicate the relevant values here. // Duplicate the relevant values here.
switch name { switch name {
// 1003.1 // 1003.1
case SC_ARG_MAX: case SC_ARG_MAX:
return sysctl32("kern.argmax"), nil return sysctl32("kern.argmax"), nil
@@ -54,14 +55,13 @@ func sysconf(name int) (int64, error) {
} }
return -1, nil return -1, nil
case SC_CLK_TCK: case SC_CLK_TCK:
// TODO: use sync.OnceValue once Go 1.21 is the minimal supported version clktckOnce.Do(func() {
clktck.Do(func() { clktck = -1
clktck.v = -1
if ci, err := unix.SysctlClockinfo("kern.clockrate"); err == nil { if ci, err := unix.SysctlClockinfo("kern.clockrate"); err == nil {
clktck.v = int64(ci.Hz) clktck = int64(ci.Hz)
} }
}) })
return clktck.v, nil return clktck, nil
case SC_NGROUPS_MAX: case SC_NGROUPS_MAX:
return sysctl32("kern.ngroups"), nil return sysctl32("kern.ngroups"), nil
case SC_JOB_CONTROL: case SC_JOB_CONTROL:

View File

@@ -1,6 +1,6 @@
env: env:
CIRRUS_CLONE_DEPTH: 1 CIRRUS_CLONE_DEPTH: 1
GO_VERSION: go1.21.3 GO_VERSION: go1.20
freebsd_12_task: freebsd_12_task:
freebsd_instance: freebsd_instance:

View File

@@ -15,6 +15,7 @@
package numcpus package numcpus
import ( import (
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
@@ -34,7 +35,7 @@ func getFromCPUAffinity() (int, error) {
} }
func readCPURange(file string) (int, error) { func readCPURange(file string) (int, error) {
buf, err := os.ReadFile(filepath.Join(sysfsCPUBasePath, file)) buf, err := ioutil.ReadFile(filepath.Join(sysfsCPUBasePath, file))
if err != nil { if err != nil {
return 0, err return 0, err
} }
@@ -47,16 +48,16 @@ func parseCPURange(cpus string) (int, error) {
if len(cpuRange) == 0 { if len(cpuRange) == 0 {
continue continue
} }
from, to, found := strings.Cut(cpuRange, "-") rangeOp := strings.SplitN(cpuRange, "-", 2)
first, err := strconv.ParseUint(from, 10, 32) first, err := strconv.ParseUint(rangeOp[0], 10, 32)
if err != nil { if err != nil {
return 0, err return 0, err
} }
if !found { if len(rangeOp) == 1 {
n++ n++
continue continue
} }
last, err := strconv.ParseUint(to, 10, 32) last, err := strconv.ParseUint(rangeOp[1], 10, 32)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@@ -88,7 +89,7 @@ func getConfigured() (int, error) {
} }
func getKernelMax() (int, error) { func getKernelMax() (int, error) {
buf, err := os.ReadFile(filepath.Join(sysfsCPUBasePath, "kernel_max")) buf, err := ioutil.ReadFile(filepath.Join(sysfsCPUBasePath, "kernel_max"))
if err != nil { if err != nil {
return 0, err return 0, err
} }

View File

@@ -9,9 +9,11 @@
#define PSALAA 1208(R0) #define PSALAA 1208(R0)
#define GTAB64(x) 80(x) #define GTAB64(x) 80(x)
#define LCA64(x) 88(x) #define LCA64(x) 88(x)
#define CAA(x) 8(x)
#define EDCHPXV(x) 1016(x) // in the CAA
#define SAVSTACK_ASYNC(x) 336(x) // in the LCA #define SAVSTACK_ASYNC(x) 336(x) // in the LCA
#define CAA(x) 8(x)
#define CEECAATHDID(x) 976(x) // in the CAA
#define EDCHPXV(x) 1016(x) // in the CAA
#define GOCB(x) 1104(x) // in the CAA
// SS_*, where x=SAVSTACK_ASYNC // SS_*, where x=SAVSTACK_ASYNC
#define SS_LE(x) 0(x) #define SS_LE(x) 0(x)
@@ -19,15 +21,38 @@
#define SS_ERRNO(x) 16(x) #define SS_ERRNO(x) 16(x)
#define SS_ERRNOJR(x) 20(x) #define SS_ERRNOJR(x) 20(x)
#define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6 // Function Descriptor Offsets
#define __errno 0x156*16
#define __err2ad 0x16C*16
TEXT ·clearErrno(SB),NOSPLIT,$0-0 // Call Instructions
#define LE_CALL BYTE $0x0D; BYTE $0x76 // BL R7, R6
#define SVC_LOAD BYTE $0x0A; BYTE $0x08 // SVC 08 LOAD
#define SVC_DELETE BYTE $0x0A; BYTE $0x09 // SVC 09 DELETE
DATA zosLibVec<>(SB)/8, $0
GLOBL zosLibVec<>(SB), NOPTR, $8
TEXT ·initZosLibVec(SB), NOSPLIT|NOFRAME, $0-0
MOVW PSALAA, R8
MOVD LCA64(R8), R8
MOVD CAA(R8), R8
MOVD EDCHPXV(R8), R8
MOVD R8, zosLibVec<>(SB)
RET
TEXT ·GetZosLibVec(SB), NOSPLIT|NOFRAME, $0-0
MOVD zosLibVec<>(SB), R8
MOVD R8, ret+0(FP)
RET
TEXT ·clearErrno(SB), NOSPLIT, $0-0
BL addrerrno<>(SB) BL addrerrno<>(SB)
MOVD $0, 0(R3) MOVD $0, 0(R3)
RET RET
// Returns the address of errno in R3. // Returns the address of errno in R3.
TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0 TEXT addrerrno<>(SB), NOSPLIT|NOFRAME, $0-0
// Get library control area (LCA). // Get library control area (LCA).
MOVW PSALAA, R8 MOVW PSALAA, R8
MOVD LCA64(R8), R8 MOVD LCA64(R8), R8
@@ -35,7 +60,7 @@ TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0
// Get __errno FuncDesc. // Get __errno FuncDesc.
MOVD CAA(R8), R9 MOVD CAA(R8), R9
MOVD EDCHPXV(R9), R9 MOVD EDCHPXV(R9), R9
ADD $(0x156*16), R9 ADD $(__errno), R9
LMG 0(R9), R5, R6 LMG 0(R9), R5, R6
// Switch to saved LE stack. // Switch to saved LE stack.
@@ -52,298 +77,8 @@ TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0
MOVD R4, 0(R9) // Save stack pointer. MOVD R4, 0(R9) // Save stack pointer.
RET RET
TEXT ·syscall_syscall(SB),NOSPLIT,$0-56
BL runtime·entersyscall(SB)
MOVD a1+8(FP), R1
MOVD a2+16(FP), R2
MOVD a3+24(FP), R3
// Get library control area (LCA).
MOVW PSALAA, R8
MOVD LCA64(R8), R8
// Get function.
MOVD CAA(R8), R9
MOVD EDCHPXV(R9), R9
MOVD trap+0(FP), R5
SLD $4, R5
ADD R5, R9
LMG 0(R9), R5, R6
// Restore LE stack.
MOVD SAVSTACK_ASYNC(R8), R9
MOVD 0(R9), R4
MOVD $0, 0(R9)
// Call function.
LE_CALL
NOPH
XOR R0, R0 // Restore R0 to $0.
MOVD R4, 0(R9) // Save stack pointer.
MOVD R3, r1+32(FP)
MOVD R0, r2+40(FP)
MOVD R0, err+48(FP)
MOVW R3, R4
CMP R4, $-1
BNE done
BL addrerrno<>(SB)
MOVWZ 0(R3), R3
MOVD R3, err+48(FP)
done:
BL runtime·exitsyscall(SB)
RET
TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56
MOVD a1+8(FP), R1
MOVD a2+16(FP), R2
MOVD a3+24(FP), R3
// Get library control area (LCA).
MOVW PSALAA, R8
MOVD LCA64(R8), R8
// Get function.
MOVD CAA(R8), R9
MOVD EDCHPXV(R9), R9
MOVD trap+0(FP), R5
SLD $4, R5
ADD R5, R9
LMG 0(R9), R5, R6
// Restore LE stack.
MOVD SAVSTACK_ASYNC(R8), R9
MOVD 0(R9), R4
MOVD $0, 0(R9)
// Call function.
LE_CALL
NOPH
XOR R0, R0 // Restore R0 to $0.
MOVD R4, 0(R9) // Save stack pointer.
MOVD R3, r1+32(FP)
MOVD R0, r2+40(FP)
MOVD R0, err+48(FP)
MOVW R3, R4
CMP R4, $-1
BNE done
BL addrerrno<>(SB)
MOVWZ 0(R3), R3
MOVD R3, err+48(FP)
done:
RET
TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80
BL runtime·entersyscall(SB)
MOVD a1+8(FP), R1
MOVD a2+16(FP), R2
MOVD a3+24(FP), R3
// Get library control area (LCA).
MOVW PSALAA, R8
MOVD LCA64(R8), R8
// Get function.
MOVD CAA(R8), R9
MOVD EDCHPXV(R9), R9
MOVD trap+0(FP), R5
SLD $4, R5
ADD R5, R9
LMG 0(R9), R5, R6
// Restore LE stack.
MOVD SAVSTACK_ASYNC(R8), R9
MOVD 0(R9), R4
MOVD $0, 0(R9)
// Fill in parameter list.
MOVD a4+32(FP), R12
MOVD R12, (2176+24)(R4)
MOVD a5+40(FP), R12
MOVD R12, (2176+32)(R4)
MOVD a6+48(FP), R12
MOVD R12, (2176+40)(R4)
// Call function.
LE_CALL
NOPH
XOR R0, R0 // Restore R0 to $0.
MOVD R4, 0(R9) // Save stack pointer.
MOVD R3, r1+56(FP)
MOVD R0, r2+64(FP)
MOVD R0, err+72(FP)
MOVW R3, R4
CMP R4, $-1
BNE done
BL addrerrno<>(SB)
MOVWZ 0(R3), R3
MOVD R3, err+72(FP)
done:
BL runtime·exitsyscall(SB)
RET
TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80
MOVD a1+8(FP), R1
MOVD a2+16(FP), R2
MOVD a3+24(FP), R3
// Get library control area (LCA).
MOVW PSALAA, R8
MOVD LCA64(R8), R8
// Get function.
MOVD CAA(R8), R9
MOVD EDCHPXV(R9), R9
MOVD trap+0(FP), R5
SLD $4, R5
ADD R5, R9
LMG 0(R9), R5, R6
// Restore LE stack.
MOVD SAVSTACK_ASYNC(R8), R9
MOVD 0(R9), R4
MOVD $0, 0(R9)
// Fill in parameter list.
MOVD a4+32(FP), R12
MOVD R12, (2176+24)(R4)
MOVD a5+40(FP), R12
MOVD R12, (2176+32)(R4)
MOVD a6+48(FP), R12
MOVD R12, (2176+40)(R4)
// Call function.
LE_CALL
NOPH
XOR R0, R0 // Restore R0 to $0.
MOVD R4, 0(R9) // Save stack pointer.
MOVD R3, r1+56(FP)
MOVD R0, r2+64(FP)
MOVD R0, err+72(FP)
MOVW R3, R4
CMP R4, $-1
BNE done
BL ·rrno<>(SB)
MOVWZ 0(R3), R3
MOVD R3, err+72(FP)
done:
RET
TEXT ·syscall_syscall9(SB),NOSPLIT,$0
BL runtime·entersyscall(SB)
MOVD a1+8(FP), R1
MOVD a2+16(FP), R2
MOVD a3+24(FP), R3
// Get library control area (LCA).
MOVW PSALAA, R8
MOVD LCA64(R8), R8
// Get function.
MOVD CAA(R8), R9
MOVD EDCHPXV(R9), R9
MOVD trap+0(FP), R5
SLD $4, R5
ADD R5, R9
LMG 0(R9), R5, R6
// Restore LE stack.
MOVD SAVSTACK_ASYNC(R8), R9
MOVD 0(R9), R4
MOVD $0, 0(R9)
// Fill in parameter list.
MOVD a4+32(FP), R12
MOVD R12, (2176+24)(R4)
MOVD a5+40(FP), R12
MOVD R12, (2176+32)(R4)
MOVD a6+48(FP), R12
MOVD R12, (2176+40)(R4)
MOVD a7+56(FP), R12
MOVD R12, (2176+48)(R4)
MOVD a8+64(FP), R12
MOVD R12, (2176+56)(R4)
MOVD a9+72(FP), R12
MOVD R12, (2176+64)(R4)
// Call function.
LE_CALL
NOPH
XOR R0, R0 // Restore R0 to $0.
MOVD R4, 0(R9) // Save stack pointer.
MOVD R3, r1+80(FP)
MOVD R0, r2+88(FP)
MOVD R0, err+96(FP)
MOVW R3, R4
CMP R4, $-1
BNE done
BL addrerrno<>(SB)
MOVWZ 0(R3), R3
MOVD R3, err+96(FP)
done:
BL runtime·exitsyscall(SB)
RET
TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0
MOVD a1+8(FP), R1
MOVD a2+16(FP), R2
MOVD a3+24(FP), R3
// Get library control area (LCA).
MOVW PSALAA, R8
MOVD LCA64(R8), R8
// Get function.
MOVD CAA(R8), R9
MOVD EDCHPXV(R9), R9
MOVD trap+0(FP), R5
SLD $4, R5
ADD R5, R9
LMG 0(R9), R5, R6
// Restore LE stack.
MOVD SAVSTACK_ASYNC(R8), R9
MOVD 0(R9), R4
MOVD $0, 0(R9)
// Fill in parameter list.
MOVD a4+32(FP), R12
MOVD R12, (2176+24)(R4)
MOVD a5+40(FP), R12
MOVD R12, (2176+32)(R4)
MOVD a6+48(FP), R12
MOVD R12, (2176+40)(R4)
MOVD a7+56(FP), R12
MOVD R12, (2176+48)(R4)
MOVD a8+64(FP), R12
MOVD R12, (2176+56)(R4)
MOVD a9+72(FP), R12
MOVD R12, (2176+64)(R4)
// Call function.
LE_CALL
NOPH
XOR R0, R0 // Restore R0 to $0.
MOVD R4, 0(R9) // Save stack pointer.
MOVD R3, r1+80(FP)
MOVD R0, r2+88(FP)
MOVD R0, err+96(FP)
MOVW R3, R4
CMP R4, $-1
BNE done
BL addrerrno<>(SB)
MOVWZ 0(R3), R3
MOVD R3, err+96(FP)
done:
RET
// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64) // func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
TEXT ·svcCall(SB),NOSPLIT,$0 TEXT ·svcCall(SB), NOSPLIT, $0
BL runtime·save_g(SB) // Save g and stack pointer BL runtime·save_g(SB) // Save g and stack pointer
MOVW PSALAA, R8 MOVW PSALAA, R8
MOVD LCA64(R8), R8 MOVD LCA64(R8), R8
@@ -366,13 +101,12 @@ TEXT ·svcCall(SB),NOSPLIT,$0
RET RET
// func svcLoad(name *byte) unsafe.Pointer // func svcLoad(name *byte) unsafe.Pointer
TEXT ·svcLoad(SB),NOSPLIT,$0 TEXT ·svcLoad(SB), NOSPLIT, $0
MOVD R15, R2 // Save go stack pointer MOVD R15, R2 // Save go stack pointer
MOVD name+0(FP), R0 // Move SVC args into registers MOVD name+0(FP), R0 // Move SVC args into registers
MOVD $0x80000000, R1 MOVD $0x80000000, R1
MOVD $0, R15 MOVD $0, R15
BYTE $0x0A // SVC 08 LOAD SVC_LOAD
BYTE $0x08
MOVW R15, R3 // Save return code from SVC MOVW R15, R3 // Save return code from SVC
MOVD R2, R15 // Restore go stack pointer MOVD R2, R15 // Restore go stack pointer
CMP R3, $0 // Check SVC return code CMP R3, $0 // Check SVC return code
@@ -380,33 +114,32 @@ TEXT ·svcLoad(SB),NOSPLIT,$0
MOVD $-2, R3 // Reset last bit of entry point to zero MOVD $-2, R3 // Reset last bit of entry point to zero
AND R0, R3 AND R0, R3
MOVD R3, addr+8(FP) // Return entry point returned by SVC MOVD R3, ret+8(FP) // Return entry point returned by SVC
CMP R0, R3 // Check if last bit of entry point was set CMP R0, R3 // Check if last bit of entry point was set
BNE done BNE done
MOVD R15, R2 // Save go stack pointer MOVD R15, R2 // Save go stack pointer
MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08) MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)
BYTE $0x0A // SVC 09 DELETE SVC_DELETE
BYTE $0x09
MOVD R2, R15 // Restore go stack pointer MOVD R2, R15 // Restore go stack pointer
error: error:
MOVD $0, addr+8(FP) // Return 0 on failure MOVD $0, ret+8(FP) // Return 0 on failure
done: done:
XOR R0, R0 // Reset r0 to 0 XOR R0, R0 // Reset r0 to 0
RET RET
// func svcUnload(name *byte, fnptr unsafe.Pointer) int64 // func svcUnload(name *byte, fnptr unsafe.Pointer) int64
TEXT ·svcUnload(SB),NOSPLIT,$0 TEXT ·svcUnload(SB), NOSPLIT, $0
MOVD R15, R2 // Save go stack pointer MOVD R15, R2 // Save go stack pointer
MOVD name+0(FP), R0 // Move SVC args into registers MOVD name+0(FP), R0 // Move SVC args into registers
MOVD addr+8(FP), R15 MOVD fnptr+8(FP), R15
BYTE $0x0A // SVC 09 SVC_DELETE
BYTE $0x09
XOR R0, R0 // Reset r0 to 0 XOR R0, R0 // Reset r0 to 0
MOVD R15, R1 // Save SVC return code MOVD R15, R1 // Save SVC return code
MOVD R2, R15 // Restore go stack pointer MOVD R2, R15 // Restore go stack pointer
MOVD R1, rc+0(FP) // Return SVC return code MOVD R1, ret+16(FP) // Return SVC return code
RET RET
// func gettid() uint64 // func gettid() uint64
@@ -417,7 +150,233 @@ TEXT ·gettid(SB), NOSPLIT, $0
// Get CEECAATHDID // Get CEECAATHDID
MOVD CAA(R8), R9 MOVD CAA(R8), R9
MOVD 0x3D0(R9), R9 MOVD CEECAATHDID(R9), R9
MOVD R9, ret+0(FP) MOVD R9, ret+0(FP)
RET RET
//
// Call LE function, if the return is -1
// errno and errno2 is retrieved
//
TEXT ·CallLeFuncWithErr(SB), NOSPLIT, $0
MOVW PSALAA, R8
MOVD LCA64(R8), R8
MOVD CAA(R8), R9
MOVD g, GOCB(R9)
// Restore LE stack.
MOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address
MOVD 0(R9), R4 // R4-> restore previously saved stack frame pointer
MOVD parms_base+8(FP), R7 // R7 -> argument array
MOVD parms_len+16(FP), R8 // R8 number of arguments
// arg 1 ---> R1
CMP R8, $0
BEQ docall
SUB $1, R8
MOVD 0(R7), R1
// arg 2 ---> R2
CMP R8, $0
BEQ docall
SUB $1, R8
ADD $8, R7
MOVD 0(R7), R2
// arg 3 --> R3
CMP R8, $0
BEQ docall
SUB $1, R8
ADD $8, R7
MOVD 0(R7), R3
CMP R8, $0
BEQ docall
MOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument
repeat:
ADD $8, R7
MOVD 0(R7), R0 // advance arg pointer by 8 byte
ADD $8, R6 // advance LE argument address by 8 byte
MOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame
SUB $1, R8
CMP R8, $0
BNE repeat
docall:
MOVD funcdesc+0(FP), R8 // R8-> function descriptor
LMG 0(R8), R5, R6
MOVD $0, 0(R9) // R9 address of SAVSTACK_ASYNC
LE_CALL // balr R7, R6 (return #1)
NOPH
MOVD R3, ret+32(FP)
CMP R3, $-1 // compare result to -1
BNE done
// retrieve errno and errno2
MOVD zosLibVec<>(SB), R8
ADD $(__errno), R8
LMG 0(R8), R5, R6
LE_CALL // balr R7, R6 __errno (return #3)
NOPH
MOVWZ 0(R3), R3
MOVD R3, err+48(FP)
MOVD zosLibVec<>(SB), R8
ADD $(__err2ad), R8
LMG 0(R8), R5, R6
LE_CALL // balr R7, R6 __err2ad (return #2)
NOPH
MOVW (R3), R2 // retrieve errno2
MOVD R2, errno2+40(FP) // store in return area
done:
MOVD R4, 0(R9) // Save stack pointer.
RET
//
// Call LE function, if the return is 0
// errno and errno2 is retrieved
//
TEXT ·CallLeFuncWithPtrReturn(SB), NOSPLIT, $0
MOVW PSALAA, R8
MOVD LCA64(R8), R8
MOVD CAA(R8), R9
MOVD g, GOCB(R9)
// Restore LE stack.
MOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address
MOVD 0(R9), R4 // R4-> restore previously saved stack frame pointer
MOVD parms_base+8(FP), R7 // R7 -> argument array
MOVD parms_len+16(FP), R8 // R8 number of arguments
// arg 1 ---> R1
CMP R8, $0
BEQ docall
SUB $1, R8
MOVD 0(R7), R1
// arg 2 ---> R2
CMP R8, $0
BEQ docall
SUB $1, R8
ADD $8, R7
MOVD 0(R7), R2
// arg 3 --> R3
CMP R8, $0
BEQ docall
SUB $1, R8
ADD $8, R7
MOVD 0(R7), R3
CMP R8, $0
BEQ docall
MOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument
repeat:
ADD $8, R7
MOVD 0(R7), R0 // advance arg pointer by 8 byte
ADD $8, R6 // advance LE argument address by 8 byte
MOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame
SUB $1, R8
CMP R8, $0
BNE repeat
docall:
MOVD funcdesc+0(FP), R8 // R8-> function descriptor
LMG 0(R8), R5, R6
MOVD $0, 0(R9) // R9 address of SAVSTACK_ASYNC
LE_CALL // balr R7, R6 (return #1)
NOPH
MOVD R3, ret+32(FP)
CMP R3, $0 // compare result to 0
BNE done
// retrieve errno and errno2
MOVD zosLibVec<>(SB), R8
ADD $(__errno), R8
LMG 0(R8), R5, R6
LE_CALL // balr R7, R6 __errno (return #3)
NOPH
MOVWZ 0(R3), R3
MOVD R3, err+48(FP)
MOVD zosLibVec<>(SB), R8
ADD $(__err2ad), R8
LMG 0(R8), R5, R6
LE_CALL // balr R7, R6 __err2ad (return #2)
NOPH
MOVW (R3), R2 // retrieve errno2
MOVD R2, errno2+40(FP) // store in return area
XOR R2, R2
MOVWZ R2, (R3) // clear errno2
done:
MOVD R4, 0(R9) // Save stack pointer.
RET
//
// function to test if a pointer can be safely dereferenced (content read)
// return 0 for succces
//
TEXT ·ptrtest(SB), NOSPLIT, $0-16
MOVD arg+0(FP), R10 // test pointer in R10
// set up R2 to point to CEECAADMC
BYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt 2,1208
BYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22 // llgtr 2,2
BYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF // nilh 2,32767
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg 2,88(2)
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg 2,8(2)
BYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68 // la 2,872(2)
// set up R5 to point to the "shunt" path which set 1 to R3 (failure)
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33 // xgr 3,3
BYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04 // bras 5,lbl1
BYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01 // lghi 3,1
// if r3 is not zero (failed) then branch to finish
BYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33 // lbl1 ltgr 3,3
BYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08 // brc b'0111',lbl2
// stomic store shunt address in R5 into CEECAADMC
BYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 5,0(2)
// now try reading from the test pointer in R10, if it fails it branches to the "lghi" instruction above
BYTE $0xE3; BYTE $0x9A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg 9,0(10)
// finish here, restore 0 into CEECAADMC
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99 // lbl2 xgr 9,9
BYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 9,0(2)
MOVD R3, ret+8(FP) // result in R3
RET
//
// function to test if a untptr can be loaded from a pointer
// return 1: the 8-byte content
// 2: 0 for success, 1 for failure
//
// func safeload(ptr uintptr) ( value uintptr, error uintptr)
TEXT ·safeload(SB), NOSPLIT, $0-24
MOVD ptr+0(FP), R10 // test pointer in R10
MOVD $0x0, R6
BYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt 2,1208
BYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22 // llgtr 2,2
BYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF // nilh 2,32767
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg 2,88(2)
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg 2,8(2)
BYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68 // la 2,872(2)
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33 // xgr 3,3
BYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04 // bras 5,lbl1
BYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01 // lghi 3,1
BYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33 // lbl1 ltgr 3,3
BYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08 // brc b'0111',lbl2
BYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 5,0(2)
BYTE $0xE3; BYTE $0x6A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg 6,0(10)
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99 // lbl2 xgr 9,9
BYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 9,0(2)
MOVD R6, value+8(FP) // result in R6
MOVD R3, error+16(FP) // error in R3
RET

657
vendor/golang.org/x/sys/unix/bpxsvc_zos.go generated vendored Normal file
View File

@@ -0,0 +1,657 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build zos
package unix
import (
"bytes"
"fmt"
"unsafe"
)
//go:noescape
func bpxcall(plist []unsafe.Pointer, bpx_offset int64)
//go:noescape
func A2e([]byte)
//go:noescape
func E2a([]byte)
const (
BPX4STA = 192 // stat
BPX4FST = 104 // fstat
BPX4LST = 132 // lstat
BPX4OPN = 156 // open
BPX4CLO = 72 // close
BPX4CHR = 500 // chattr
BPX4FCR = 504 // fchattr
BPX4LCR = 1180 // lchattr
BPX4CTW = 492 // cond_timed_wait
BPX4GTH = 1056 // __getthent
BPX4PTQ = 412 // pthread_quiesc
BPX4PTR = 320 // ptrace
)
const (
//options
//byte1
BPX_OPNFHIGH = 0x80
//byte2
BPX_OPNFEXEC = 0x80
//byte3
BPX_O_NOLARGEFILE = 0x08
BPX_O_LARGEFILE = 0x04
BPX_O_ASYNCSIG = 0x02
BPX_O_SYNC = 0x01
//byte4
BPX_O_CREXCL = 0xc0
BPX_O_CREAT = 0x80
BPX_O_EXCL = 0x40
BPX_O_NOCTTY = 0x20
BPX_O_TRUNC = 0x10
BPX_O_APPEND = 0x08
BPX_O_NONBLOCK = 0x04
BPX_FNDELAY = 0x04
BPX_O_RDWR = 0x03
BPX_O_RDONLY = 0x02
BPX_O_WRONLY = 0x01
BPX_O_ACCMODE = 0x03
BPX_O_GETFL = 0x0f
//mode
// byte1 (file type)
BPX_FT_DIR = 1
BPX_FT_CHARSPEC = 2
BPX_FT_REGFILE = 3
BPX_FT_FIFO = 4
BPX_FT_SYMLINK = 5
BPX_FT_SOCKET = 6
//byte3
BPX_S_ISUID = 0x08
BPX_S_ISGID = 0x04
BPX_S_ISVTX = 0x02
BPX_S_IRWXU1 = 0x01
BPX_S_IRUSR = 0x01
//byte4
BPX_S_IRWXU2 = 0xc0
BPX_S_IWUSR = 0x80
BPX_S_IXUSR = 0x40
BPX_S_IRWXG = 0x38
BPX_S_IRGRP = 0x20
BPX_S_IWGRP = 0x10
BPX_S_IXGRP = 0x08
BPX_S_IRWXOX = 0x07
BPX_S_IROTH = 0x04
BPX_S_IWOTH = 0x02
BPX_S_IXOTH = 0x01
CW_INTRPT = 1
CW_CONDVAR = 32
CW_TIMEOUT = 64
PGTHA_NEXT = 2
PGTHA_CURRENT = 1
PGTHA_FIRST = 0
PGTHA_LAST = 3
PGTHA_PROCESS = 0x80
PGTHA_CONTTY = 0x40
PGTHA_PATH = 0x20
PGTHA_COMMAND = 0x10
PGTHA_FILEDATA = 0x08
PGTHA_THREAD = 0x04
PGTHA_PTAG = 0x02
PGTHA_COMMANDLONG = 0x01
PGTHA_THREADFAST = 0x80
PGTHA_FILEPATH = 0x40
PGTHA_THDSIGMASK = 0x20
// thread quiece mode
QUIESCE_TERM int32 = 1
QUIESCE_FORCE int32 = 2
QUIESCE_QUERY int32 = 3
QUIESCE_FREEZE int32 = 4
QUIESCE_UNFREEZE int32 = 5
FREEZE_THIS_THREAD int32 = 6
FREEZE_EXIT int32 = 8
QUIESCE_SRB int32 = 9
)
type Pgtha struct {
Pid uint32 // 0
Tid0 uint32 // 4
Tid1 uint32
Accesspid byte // C
Accesstid byte // D
Accessasid uint16 // E
Loginname [8]byte // 10
Flag1 byte // 18
Flag1b2 byte // 19
}
type Bpxystat_t struct { // DSECT BPXYSTAT
St_id [4]uint8 // 0
St_length uint16 // 0x4
St_version uint16 // 0x6
St_mode uint32 // 0x8
St_ino uint32 // 0xc
St_dev uint32 // 0x10
St_nlink uint32 // 0x14
St_uid uint32 // 0x18
St_gid uint32 // 0x1c
St_size uint64 // 0x20
St_atime uint32 // 0x28
St_mtime uint32 // 0x2c
St_ctime uint32 // 0x30
St_rdev uint32 // 0x34
St_auditoraudit uint32 // 0x38
St_useraudit uint32 // 0x3c
St_blksize uint32 // 0x40
St_createtime uint32 // 0x44
St_auditid [4]uint32 // 0x48
St_res01 uint32 // 0x58
Ft_ccsid uint16 // 0x5c
Ft_flags uint16 // 0x5e
St_res01a [2]uint32 // 0x60
St_res02 uint32 // 0x68
St_blocks uint32 // 0x6c
St_opaque [3]uint8 // 0x70
St_visible uint8 // 0x73
St_reftime uint32 // 0x74
St_fid uint64 // 0x78
St_filefmt uint8 // 0x80
St_fspflag2 uint8 // 0x81
St_res03 [2]uint8 // 0x82
St_ctimemsec uint32 // 0x84
St_seclabel [8]uint8 // 0x88
St_res04 [4]uint8 // 0x90
// end of version 1
_ uint32 // 0x94
St_atime64 uint64 // 0x98
St_mtime64 uint64 // 0xa0
St_ctime64 uint64 // 0xa8
St_createtime64 uint64 // 0xb0
St_reftime64 uint64 // 0xb8
_ uint64 // 0xc0
St_res05 [16]uint8 // 0xc8
// end of version 2
}
type BpxFilestatus struct {
Oflag1 byte
Oflag2 byte
Oflag3 byte
Oflag4 byte
}
type BpxMode struct {
Ftype byte
Mode1 byte
Mode2 byte
Mode3 byte
}
// Thr attribute structure for extended attributes
type Bpxyatt_t struct { // DSECT BPXYATT
Att_id [4]uint8
Att_version uint16
Att_res01 [2]uint8
Att_setflags1 uint8
Att_setflags2 uint8
Att_setflags3 uint8
Att_setflags4 uint8
Att_mode uint32
Att_uid uint32
Att_gid uint32
Att_opaquemask [3]uint8
Att_visblmaskres uint8
Att_opaque [3]uint8
Att_visibleres uint8
Att_size_h uint32
Att_size_l uint32
Att_atime uint32
Att_mtime uint32
Att_auditoraudit uint32
Att_useraudit uint32
Att_ctime uint32
Att_reftime uint32
// end of version 1
Att_filefmt uint8
Att_res02 [3]uint8
Att_filetag uint32
Att_res03 [8]uint8
// end of version 2
Att_atime64 uint64
Att_mtime64 uint64
Att_ctime64 uint64
Att_reftime64 uint64
Att_seclabel [8]uint8
Att_ver3res02 [8]uint8
// end of version 3
}
func BpxOpen(name string, options *BpxFilestatus, mode *BpxMode) (rv int32, rc int32, rn int32) {
if len(name) < 1024 {
var namebuf [1024]byte
sz := int32(copy(namebuf[:], name))
A2e(namebuf[:sz])
var parms [7]unsafe.Pointer
parms[0] = unsafe.Pointer(&sz)
parms[1] = unsafe.Pointer(&namebuf[0])
parms[2] = unsafe.Pointer(options)
parms[3] = unsafe.Pointer(mode)
parms[4] = unsafe.Pointer(&rv)
parms[5] = unsafe.Pointer(&rc)
parms[6] = unsafe.Pointer(&rn)
bpxcall(parms[:], BPX4OPN)
return rv, rc, rn
}
return -1, -1, -1
}
func BpxClose(fd int32) (rv int32, rc int32, rn int32) {
var parms [4]unsafe.Pointer
parms[0] = unsafe.Pointer(&fd)
parms[1] = unsafe.Pointer(&rv)
parms[2] = unsafe.Pointer(&rc)
parms[3] = unsafe.Pointer(&rn)
bpxcall(parms[:], BPX4CLO)
return rv, rc, rn
}
func BpxFileFStat(fd int32, st *Bpxystat_t) (rv int32, rc int32, rn int32) {
st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}
st.St_version = 2
stat_sz := uint32(unsafe.Sizeof(*st))
var parms [6]unsafe.Pointer
parms[0] = unsafe.Pointer(&fd)
parms[1] = unsafe.Pointer(&stat_sz)
parms[2] = unsafe.Pointer(st)
parms[3] = unsafe.Pointer(&rv)
parms[4] = unsafe.Pointer(&rc)
parms[5] = unsafe.Pointer(&rn)
bpxcall(parms[:], BPX4FST)
return rv, rc, rn
}
func BpxFileStat(name string, st *Bpxystat_t) (rv int32, rc int32, rn int32) {
if len(name) < 1024 {
var namebuf [1024]byte
sz := int32(copy(namebuf[:], name))
A2e(namebuf[:sz])
st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}
st.St_version = 2
stat_sz := uint32(unsafe.Sizeof(*st))
var parms [7]unsafe.Pointer
parms[0] = unsafe.Pointer(&sz)
parms[1] = unsafe.Pointer(&namebuf[0])
parms[2] = unsafe.Pointer(&stat_sz)
parms[3] = unsafe.Pointer(st)
parms[4] = unsafe.Pointer(&rv)
parms[5] = unsafe.Pointer(&rc)
parms[6] = unsafe.Pointer(&rn)
bpxcall(parms[:], BPX4STA)
return rv, rc, rn
}
return -1, -1, -1
}
func BpxFileLStat(name string, st *Bpxystat_t) (rv int32, rc int32, rn int32) {
if len(name) < 1024 {
var namebuf [1024]byte
sz := int32(copy(namebuf[:], name))
A2e(namebuf[:sz])
st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}
st.St_version = 2
stat_sz := uint32(unsafe.Sizeof(*st))
var parms [7]unsafe.Pointer
parms[0] = unsafe.Pointer(&sz)
parms[1] = unsafe.Pointer(&namebuf[0])
parms[2] = unsafe.Pointer(&stat_sz)
parms[3] = unsafe.Pointer(st)
parms[4] = unsafe.Pointer(&rv)
parms[5] = unsafe.Pointer(&rc)
parms[6] = unsafe.Pointer(&rn)
bpxcall(parms[:], BPX4LST)
return rv, rc, rn
}
return -1, -1, -1
}
func BpxChattr(path string, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {
if len(path) >= 1024 {
return -1, -1, -1
}
var namebuf [1024]byte
sz := int32(copy(namebuf[:], path))
A2e(namebuf[:sz])
attr_sz := uint32(unsafe.Sizeof(*attr))
var parms [7]unsafe.Pointer
parms[0] = unsafe.Pointer(&sz)
parms[1] = unsafe.Pointer(&namebuf[0])
parms[2] = unsafe.Pointer(&attr_sz)
parms[3] = unsafe.Pointer(attr)
parms[4] = unsafe.Pointer(&rv)
parms[5] = unsafe.Pointer(&rc)
parms[6] = unsafe.Pointer(&rn)
bpxcall(parms[:], BPX4CHR)
return rv, rc, rn
}
func BpxLchattr(path string, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {
if len(path) >= 1024 {
return -1, -1, -1
}
var namebuf [1024]byte
sz := int32(copy(namebuf[:], path))
A2e(namebuf[:sz])
attr_sz := uint32(unsafe.Sizeof(*attr))
var parms [7]unsafe.Pointer
parms[0] = unsafe.Pointer(&sz)
parms[1] = unsafe.Pointer(&namebuf[0])
parms[2] = unsafe.Pointer(&attr_sz)
parms[3] = unsafe.Pointer(attr)
parms[4] = unsafe.Pointer(&rv)
parms[5] = unsafe.Pointer(&rc)
parms[6] = unsafe.Pointer(&rn)
bpxcall(parms[:], BPX4LCR)
return rv, rc, rn
}
func BpxFchattr(fd int32, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {
attr_sz := uint32(unsafe.Sizeof(*attr))
var parms [6]unsafe.Pointer
parms[0] = unsafe.Pointer(&fd)
parms[1] = unsafe.Pointer(&attr_sz)
parms[2] = unsafe.Pointer(attr)
parms[3] = unsafe.Pointer(&rv)
parms[4] = unsafe.Pointer(&rc)
parms[5] = unsafe.Pointer(&rn)
bpxcall(parms[:], BPX4FCR)
return rv, rc, rn
}
func BpxCondTimedWait(sec uint32, nsec uint32, events uint32, secrem *uint32, nsecrem *uint32) (rv int32, rc int32, rn int32) {
var parms [8]unsafe.Pointer
parms[0] = unsafe.Pointer(&sec)
parms[1] = unsafe.Pointer(&nsec)
parms[2] = unsafe.Pointer(&events)
parms[3] = unsafe.Pointer(secrem)
parms[4] = unsafe.Pointer(nsecrem)
parms[5] = unsafe.Pointer(&rv)
parms[6] = unsafe.Pointer(&rc)
parms[7] = unsafe.Pointer(&rn)
bpxcall(parms[:], BPX4CTW)
return rv, rc, rn
}
func BpxGetthent(in *Pgtha, outlen *uint32, out unsafe.Pointer) (rv int32, rc int32, rn int32) {
var parms [7]unsafe.Pointer
inlen := uint32(26) // nothing else will work. Go says Pgtha is 28-byte because of alignment, but Pgtha is "packed" and must be 26-byte
parms[0] = unsafe.Pointer(&inlen)
parms[1] = unsafe.Pointer(&in)
parms[2] = unsafe.Pointer(outlen)
parms[3] = unsafe.Pointer(&out)
parms[4] = unsafe.Pointer(&rv)
parms[5] = unsafe.Pointer(&rc)
parms[6] = unsafe.Pointer(&rn)
bpxcall(parms[:], BPX4GTH)
return rv, rc, rn
}
func ZosJobname() (jobname string, err error) {
var pgtha Pgtha
pgtha.Pid = uint32(Getpid())
pgtha.Accesspid = PGTHA_CURRENT
pgtha.Flag1 = PGTHA_PROCESS
var out [256]byte
var outlen uint32
outlen = 256
rv, rc, rn := BpxGetthent(&pgtha, &outlen, unsafe.Pointer(&out[0]))
if rv == 0 {
gthc := []byte{0x87, 0xa3, 0x88, 0x83} // 'gthc' in ebcdic
ix := bytes.Index(out[:], gthc)
if ix == -1 {
err = fmt.Errorf("BPX4GTH: gthc return data not found")
return
}
jn := out[ix+80 : ix+88] // we didn't declare Pgthc, but jobname is 8-byte at offset 80
E2a(jn)
jobname = string(bytes.TrimRight(jn, " "))
} else {
err = fmt.Errorf("BPX4GTH: rc=%d errno=%d reason=code=0x%x", rv, rc, rn)
}
return
}
func Bpx4ptq(code int32, data string) (rv int32, rc int32, rn int32) {
var userdata [8]byte
var parms [5]unsafe.Pointer
copy(userdata[:], data+" ")
A2e(userdata[:])
parms[0] = unsafe.Pointer(&code)
parms[1] = unsafe.Pointer(&userdata[0])
parms[2] = unsafe.Pointer(&rv)
parms[3] = unsafe.Pointer(&rc)
parms[4] = unsafe.Pointer(&rn)
bpxcall(parms[:], BPX4PTQ)
return rv, rc, rn
}
const (
PT_TRACE_ME = 0 // Debug this process
PT_READ_I = 1 // Read a full word
PT_READ_D = 2 // Read a full word
PT_READ_U = 3 // Read control info
PT_WRITE_I = 4 //Write a full word
PT_WRITE_D = 5 //Write a full word
PT_CONTINUE = 7 //Continue the process
PT_KILL = 8 //Terminate the process
PT_READ_GPR = 11 // Read GPR, CR, PSW
PT_READ_FPR = 12 // Read FPR
PT_READ_VR = 13 // Read VR
PT_WRITE_GPR = 14 // Write GPR, CR, PSW
PT_WRITE_FPR = 15 // Write FPR
PT_WRITE_VR = 16 // Write VR
PT_READ_BLOCK = 17 // Read storage
PT_WRITE_BLOCK = 19 // Write storage
PT_READ_GPRH = 20 // Read GPRH
PT_WRITE_GPRH = 21 // Write GPRH
PT_REGHSET = 22 // Read all GPRHs
PT_ATTACH = 30 // Attach to a process
PT_DETACH = 31 // Detach from a process
PT_REGSET = 32 // Read all GPRs
PT_REATTACH = 33 // Reattach to a process
PT_LDINFO = 34 // Read loader info
PT_MULTI = 35 // Multi process mode
PT_LD64INFO = 36 // RMODE64 Info Area
PT_BLOCKREQ = 40 // Block request
PT_THREAD_INFO = 60 // Read thread info
PT_THREAD_MODIFY = 61
PT_THREAD_READ_FOCUS = 62
PT_THREAD_WRITE_FOCUS = 63
PT_THREAD_HOLD = 64
PT_THREAD_SIGNAL = 65
PT_EXPLAIN = 66
PT_EVENTS = 67
PT_THREAD_INFO_EXTENDED = 68
PT_REATTACH2 = 71
PT_CAPTURE = 72
PT_UNCAPTURE = 73
PT_GET_THREAD_TCB = 74
PT_GET_ALET = 75
PT_SWAPIN = 76
PT_EXTENDED_EVENT = 98
PT_RECOVER = 99 // Debug a program check
PT_GPR0 = 0 // General purpose register 0
PT_GPR1 = 1 // General purpose register 1
PT_GPR2 = 2 // General purpose register 2
PT_GPR3 = 3 // General purpose register 3
PT_GPR4 = 4 // General purpose register 4
PT_GPR5 = 5 // General purpose register 5
PT_GPR6 = 6 // General purpose register 6
PT_GPR7 = 7 // General purpose register 7
PT_GPR8 = 8 // General purpose register 8
PT_GPR9 = 9 // General purpose register 9
PT_GPR10 = 10 // General purpose register 10
PT_GPR11 = 11 // General purpose register 11
PT_GPR12 = 12 // General purpose register 12
PT_GPR13 = 13 // General purpose register 13
PT_GPR14 = 14 // General purpose register 14
PT_GPR15 = 15 // General purpose register 15
PT_FPR0 = 16 // Floating point register 0
PT_FPR1 = 17 // Floating point register 1
PT_FPR2 = 18 // Floating point register 2
PT_FPR3 = 19 // Floating point register 3
PT_FPR4 = 20 // Floating point register 4
PT_FPR5 = 21 // Floating point register 5
PT_FPR6 = 22 // Floating point register 6
PT_FPR7 = 23 // Floating point register 7
PT_FPR8 = 24 // Floating point register 8
PT_FPR9 = 25 // Floating point register 9
PT_FPR10 = 26 // Floating point register 10
PT_FPR11 = 27 // Floating point register 11
PT_FPR12 = 28 // Floating point register 12
PT_FPR13 = 29 // Floating point register 13
PT_FPR14 = 30 // Floating point register 14
PT_FPR15 = 31 // Floating point register 15
PT_FPC = 32 // Floating point control register
PT_PSW = 40 // PSW
PT_PSW0 = 40 // Left half of the PSW
PT_PSW1 = 41 // Right half of the PSW
PT_CR0 = 42 // Control register 0
PT_CR1 = 43 // Control register 1
PT_CR2 = 44 // Control register 2
PT_CR3 = 45 // Control register 3
PT_CR4 = 46 // Control register 4
PT_CR5 = 47 // Control register 5
PT_CR6 = 48 // Control register 6
PT_CR7 = 49 // Control register 7
PT_CR8 = 50 // Control register 8
PT_CR9 = 51 // Control register 9
PT_CR10 = 52 // Control register 10
PT_CR11 = 53 // Control register 11
PT_CR12 = 54 // Control register 12
PT_CR13 = 55 // Control register 13
PT_CR14 = 56 // Control register 14
PT_CR15 = 57 // Control register 15
PT_GPRH0 = 58 // GP High register 0
PT_GPRH1 = 59 // GP High register 1
PT_GPRH2 = 60 // GP High register 2
PT_GPRH3 = 61 // GP High register 3
PT_GPRH4 = 62 // GP High register 4
PT_GPRH5 = 63 // GP High register 5
PT_GPRH6 = 64 // GP High register 6
PT_GPRH7 = 65 // GP High register 7
PT_GPRH8 = 66 // GP High register 8
PT_GPRH9 = 67 // GP High register 9
PT_GPRH10 = 68 // GP High register 10
PT_GPRH11 = 69 // GP High register 11
PT_GPRH12 = 70 // GP High register 12
PT_GPRH13 = 71 // GP High register 13
PT_GPRH14 = 72 // GP High register 14
PT_GPRH15 = 73 // GP High register 15
PT_VR0 = 74 // Vector register 0
PT_VR1 = 75 // Vector register 1
PT_VR2 = 76 // Vector register 2
PT_VR3 = 77 // Vector register 3
PT_VR4 = 78 // Vector register 4
PT_VR5 = 79 // Vector register 5
PT_VR6 = 80 // Vector register 6
PT_VR7 = 81 // Vector register 7
PT_VR8 = 82 // Vector register 8
PT_VR9 = 83 // Vector register 9
PT_VR10 = 84 // Vector register 10
PT_VR11 = 85 // Vector register 11
PT_VR12 = 86 // Vector register 12
PT_VR13 = 87 // Vector register 13
PT_VR14 = 88 // Vector register 14
PT_VR15 = 89 // Vector register 15
PT_VR16 = 90 // Vector register 16
PT_VR17 = 91 // Vector register 17
PT_VR18 = 92 // Vector register 18
PT_VR19 = 93 // Vector register 19
PT_VR20 = 94 // Vector register 20
PT_VR21 = 95 // Vector register 21
PT_VR22 = 96 // Vector register 22
PT_VR23 = 97 // Vector register 23
PT_VR24 = 98 // Vector register 24
PT_VR25 = 99 // Vector register 25
PT_VR26 = 100 // Vector register 26
PT_VR27 = 101 // Vector register 27
PT_VR28 = 102 // Vector register 28
PT_VR29 = 103 // Vector register 29
PT_VR30 = 104 // Vector register 30
PT_VR31 = 105 // Vector register 31
PT_PSWG = 106 // PSWG
PT_PSWG0 = 106 // Bytes 0-3
PT_PSWG1 = 107 // Bytes 4-7
PT_PSWG2 = 108 // Bytes 8-11 (IA high word)
PT_PSWG3 = 109 // Bytes 12-15 (IA low word)
)
func Bpx4ptr(request int32, pid int32, addr unsafe.Pointer, data unsafe.Pointer, buffer unsafe.Pointer) (rv int32, rc int32, rn int32) {
var parms [8]unsafe.Pointer
parms[0] = unsafe.Pointer(&request)
parms[1] = unsafe.Pointer(&pid)
parms[2] = unsafe.Pointer(&addr)
parms[3] = unsafe.Pointer(&data)
parms[4] = unsafe.Pointer(&buffer)
parms[5] = unsafe.Pointer(&rv)
parms[6] = unsafe.Pointer(&rc)
parms[7] = unsafe.Pointer(&rn)
bpxcall(parms[:], BPX4PTR)
return rv, rc, rn
}
func copyU8(val uint8, dest []uint8) int {
if len(dest) < 1 {
return 0
}
dest[0] = val
return 1
}
func copyU8Arr(src, dest []uint8) int {
if len(dest) < len(src) {
return 0
}
for i, v := range src {
dest[i] = v
}
return len(src)
}
func copyU16(val uint16, dest []uint16) int {
if len(dest) < 1 {
return 0
}
dest[0] = val
return 1
}
func copyU32(val uint32, dest []uint32) int {
if len(dest) < 1 {
return 0
}
dest[0] = val
return 1
}
func copyU32Arr(src, dest []uint32) int {
if len(dest) < len(src) {
return 0
}
for i, v := range src {
dest[i] = v
}
return len(src)
}
func copyU64(val uint64, dest []uint64) int {
if len(dest) < 1 {
return 0
}
dest[0] = val
return 1
}

192
vendor/golang.org/x/sys/unix/bpxsvc_zos.s generated vendored Normal file
View File

@@ -0,0 +1,192 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "go_asm.h"
#include "textflag.h"
// function to call USS assembly language services
//
// doc: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_3.1.0/com.ibm.zos.v3r1.bpxb100/bit64env.htm
//
// arg1 unsafe.Pointer array that ressembles an OS PLIST
//
// arg2 function offset as in
// doc: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_3.1.0/com.ibm.zos.v3r1.bpxb100/bpx2cr_List_of_offsets.htm
//
// func bpxcall(plist []unsafe.Pointer, bpx_offset int64)
TEXT ·bpxcall(SB), NOSPLIT|NOFRAME, $0
MOVD plist_base+0(FP), R1 // r1 points to plist
MOVD bpx_offset+24(FP), R2 // r2 offset to BPX vector table
MOVD R14, R7 // save r14
MOVD R15, R8 // save r15
MOVWZ 16(R0), R9
MOVWZ 544(R9), R9
MOVWZ 24(R9), R9 // call vector in r9
ADD R2, R9 // add offset to vector table
MOVWZ (R9), R9 // r9 points to entry point
BYTE $0x0D // BL R14,R9 --> basr r14,r9
BYTE $0xE9 // clobbers 0,1,14,15
MOVD R8, R15 // restore 15
JMP R7 // return via saved return address
// func A2e(arr [] byte)
// code page conversion from 819 to 1047
TEXT ·A2e(SB), NOSPLIT|NOFRAME, $0
MOVD arg_base+0(FP), R2 // pointer to arry of characters
MOVD arg_len+8(FP), R3 // count
XOR R0, R0
XOR R1, R1
BYTE $0xA7; BYTE $0x15; BYTE $0x00; BYTE $0x82 // BRAS 1,(2+(256/2))
// ASCII -> EBCDIC conversion table:
BYTE $0x00; BYTE $0x01; BYTE $0x02; BYTE $0x03
BYTE $0x37; BYTE $0x2d; BYTE $0x2e; BYTE $0x2f
BYTE $0x16; BYTE $0x05; BYTE $0x15; BYTE $0x0b
BYTE $0x0c; BYTE $0x0d; BYTE $0x0e; BYTE $0x0f
BYTE $0x10; BYTE $0x11; BYTE $0x12; BYTE $0x13
BYTE $0x3c; BYTE $0x3d; BYTE $0x32; BYTE $0x26
BYTE $0x18; BYTE $0x19; BYTE $0x3f; BYTE $0x27
BYTE $0x1c; BYTE $0x1d; BYTE $0x1e; BYTE $0x1f
BYTE $0x40; BYTE $0x5a; BYTE $0x7f; BYTE $0x7b
BYTE $0x5b; BYTE $0x6c; BYTE $0x50; BYTE $0x7d
BYTE $0x4d; BYTE $0x5d; BYTE $0x5c; BYTE $0x4e
BYTE $0x6b; BYTE $0x60; BYTE $0x4b; BYTE $0x61
BYTE $0xf0; BYTE $0xf1; BYTE $0xf2; BYTE $0xf3
BYTE $0xf4; BYTE $0xf5; BYTE $0xf6; BYTE $0xf7
BYTE $0xf8; BYTE $0xf9; BYTE $0x7a; BYTE $0x5e
BYTE $0x4c; BYTE $0x7e; BYTE $0x6e; BYTE $0x6f
BYTE $0x7c; BYTE $0xc1; BYTE $0xc2; BYTE $0xc3
BYTE $0xc4; BYTE $0xc5; BYTE $0xc6; BYTE $0xc7
BYTE $0xc8; BYTE $0xc9; BYTE $0xd1; BYTE $0xd2
BYTE $0xd3; BYTE $0xd4; BYTE $0xd5; BYTE $0xd6
BYTE $0xd7; BYTE $0xd8; BYTE $0xd9; BYTE $0xe2
BYTE $0xe3; BYTE $0xe4; BYTE $0xe5; BYTE $0xe6
BYTE $0xe7; BYTE $0xe8; BYTE $0xe9; BYTE $0xad
BYTE $0xe0; BYTE $0xbd; BYTE $0x5f; BYTE $0x6d
BYTE $0x79; BYTE $0x81; BYTE $0x82; BYTE $0x83
BYTE $0x84; BYTE $0x85; BYTE $0x86; BYTE $0x87
BYTE $0x88; BYTE $0x89; BYTE $0x91; BYTE $0x92
BYTE $0x93; BYTE $0x94; BYTE $0x95; BYTE $0x96
BYTE $0x97; BYTE $0x98; BYTE $0x99; BYTE $0xa2
BYTE $0xa3; BYTE $0xa4; BYTE $0xa5; BYTE $0xa6
BYTE $0xa7; BYTE $0xa8; BYTE $0xa9; BYTE $0xc0
BYTE $0x4f; BYTE $0xd0; BYTE $0xa1; BYTE $0x07
BYTE $0x20; BYTE $0x21; BYTE $0x22; BYTE $0x23
BYTE $0x24; BYTE $0x25; BYTE $0x06; BYTE $0x17
BYTE $0x28; BYTE $0x29; BYTE $0x2a; BYTE $0x2b
BYTE $0x2c; BYTE $0x09; BYTE $0x0a; BYTE $0x1b
BYTE $0x30; BYTE $0x31; BYTE $0x1a; BYTE $0x33
BYTE $0x34; BYTE $0x35; BYTE $0x36; BYTE $0x08
BYTE $0x38; BYTE $0x39; BYTE $0x3a; BYTE $0x3b
BYTE $0x04; BYTE $0x14; BYTE $0x3e; BYTE $0xff
BYTE $0x41; BYTE $0xaa; BYTE $0x4a; BYTE $0xb1
BYTE $0x9f; BYTE $0xb2; BYTE $0x6a; BYTE $0xb5
BYTE $0xbb; BYTE $0xb4; BYTE $0x9a; BYTE $0x8a
BYTE $0xb0; BYTE $0xca; BYTE $0xaf; BYTE $0xbc
BYTE $0x90; BYTE $0x8f; BYTE $0xea; BYTE $0xfa
BYTE $0xbe; BYTE $0xa0; BYTE $0xb6; BYTE $0xb3
BYTE $0x9d; BYTE $0xda; BYTE $0x9b; BYTE $0x8b
BYTE $0xb7; BYTE $0xb8; BYTE $0xb9; BYTE $0xab
BYTE $0x64; BYTE $0x65; BYTE $0x62; BYTE $0x66
BYTE $0x63; BYTE $0x67; BYTE $0x9e; BYTE $0x68
BYTE $0x74; BYTE $0x71; BYTE $0x72; BYTE $0x73
BYTE $0x78; BYTE $0x75; BYTE $0x76; BYTE $0x77
BYTE $0xac; BYTE $0x69; BYTE $0xed; BYTE $0xee
BYTE $0xeb; BYTE $0xef; BYTE $0xec; BYTE $0xbf
BYTE $0x80; BYTE $0xfd; BYTE $0xfe; BYTE $0xfb
BYTE $0xfc; BYTE $0xba; BYTE $0xae; BYTE $0x59
BYTE $0x44; BYTE $0x45; BYTE $0x42; BYTE $0x46
BYTE $0x43; BYTE $0x47; BYTE $0x9c; BYTE $0x48
BYTE $0x54; BYTE $0x51; BYTE $0x52; BYTE $0x53
BYTE $0x58; BYTE $0x55; BYTE $0x56; BYTE $0x57
BYTE $0x8c; BYTE $0x49; BYTE $0xcd; BYTE $0xce
BYTE $0xcb; BYTE $0xcf; BYTE $0xcc; BYTE $0xe1
BYTE $0x70; BYTE $0xdd; BYTE $0xde; BYTE $0xdb
BYTE $0xdc; BYTE $0x8d; BYTE $0x8e; BYTE $0xdf
retry:
WORD $0xB9931022 // TROO 2,2,b'0001'
BVS retry
RET
// func e2a(arr [] byte)
// code page conversion from 1047 to 819
TEXT ·E2a(SB), NOSPLIT|NOFRAME, $0
MOVD arg_base+0(FP), R2 // pointer to arry of characters
MOVD arg_len+8(FP), R3 // count
XOR R0, R0
XOR R1, R1
BYTE $0xA7; BYTE $0x15; BYTE $0x00; BYTE $0x82 // BRAS 1,(2+(256/2))
// EBCDIC -> ASCII conversion table:
BYTE $0x00; BYTE $0x01; BYTE $0x02; BYTE $0x03
BYTE $0x9c; BYTE $0x09; BYTE $0x86; BYTE $0x7f
BYTE $0x97; BYTE $0x8d; BYTE $0x8e; BYTE $0x0b
BYTE $0x0c; BYTE $0x0d; BYTE $0x0e; BYTE $0x0f
BYTE $0x10; BYTE $0x11; BYTE $0x12; BYTE $0x13
BYTE $0x9d; BYTE $0x0a; BYTE $0x08; BYTE $0x87
BYTE $0x18; BYTE $0x19; BYTE $0x92; BYTE $0x8f
BYTE $0x1c; BYTE $0x1d; BYTE $0x1e; BYTE $0x1f
BYTE $0x80; BYTE $0x81; BYTE $0x82; BYTE $0x83
BYTE $0x84; BYTE $0x85; BYTE $0x17; BYTE $0x1b
BYTE $0x88; BYTE $0x89; BYTE $0x8a; BYTE $0x8b
BYTE $0x8c; BYTE $0x05; BYTE $0x06; BYTE $0x07
BYTE $0x90; BYTE $0x91; BYTE $0x16; BYTE $0x93
BYTE $0x94; BYTE $0x95; BYTE $0x96; BYTE $0x04
BYTE $0x98; BYTE $0x99; BYTE $0x9a; BYTE $0x9b
BYTE $0x14; BYTE $0x15; BYTE $0x9e; BYTE $0x1a
BYTE $0x20; BYTE $0xa0; BYTE $0xe2; BYTE $0xe4
BYTE $0xe0; BYTE $0xe1; BYTE $0xe3; BYTE $0xe5
BYTE $0xe7; BYTE $0xf1; BYTE $0xa2; BYTE $0x2e
BYTE $0x3c; BYTE $0x28; BYTE $0x2b; BYTE $0x7c
BYTE $0x26; BYTE $0xe9; BYTE $0xea; BYTE $0xeb
BYTE $0xe8; BYTE $0xed; BYTE $0xee; BYTE $0xef
BYTE $0xec; BYTE $0xdf; BYTE $0x21; BYTE $0x24
BYTE $0x2a; BYTE $0x29; BYTE $0x3b; BYTE $0x5e
BYTE $0x2d; BYTE $0x2f; BYTE $0xc2; BYTE $0xc4
BYTE $0xc0; BYTE $0xc1; BYTE $0xc3; BYTE $0xc5
BYTE $0xc7; BYTE $0xd1; BYTE $0xa6; BYTE $0x2c
BYTE $0x25; BYTE $0x5f; BYTE $0x3e; BYTE $0x3f
BYTE $0xf8; BYTE $0xc9; BYTE $0xca; BYTE $0xcb
BYTE $0xc8; BYTE $0xcd; BYTE $0xce; BYTE $0xcf
BYTE $0xcc; BYTE $0x60; BYTE $0x3a; BYTE $0x23
BYTE $0x40; BYTE $0x27; BYTE $0x3d; BYTE $0x22
BYTE $0xd8; BYTE $0x61; BYTE $0x62; BYTE $0x63
BYTE $0x64; BYTE $0x65; BYTE $0x66; BYTE $0x67
BYTE $0x68; BYTE $0x69; BYTE $0xab; BYTE $0xbb
BYTE $0xf0; BYTE $0xfd; BYTE $0xfe; BYTE $0xb1
BYTE $0xb0; BYTE $0x6a; BYTE $0x6b; BYTE $0x6c
BYTE $0x6d; BYTE $0x6e; BYTE $0x6f; BYTE $0x70
BYTE $0x71; BYTE $0x72; BYTE $0xaa; BYTE $0xba
BYTE $0xe6; BYTE $0xb8; BYTE $0xc6; BYTE $0xa4
BYTE $0xb5; BYTE $0x7e; BYTE $0x73; BYTE $0x74
BYTE $0x75; BYTE $0x76; BYTE $0x77; BYTE $0x78
BYTE $0x79; BYTE $0x7a; BYTE $0xa1; BYTE $0xbf
BYTE $0xd0; BYTE $0x5b; BYTE $0xde; BYTE $0xae
BYTE $0xac; BYTE $0xa3; BYTE $0xa5; BYTE $0xb7
BYTE $0xa9; BYTE $0xa7; BYTE $0xb6; BYTE $0xbc
BYTE $0xbd; BYTE $0xbe; BYTE $0xdd; BYTE $0xa8
BYTE $0xaf; BYTE $0x5d; BYTE $0xb4; BYTE $0xd7
BYTE $0x7b; BYTE $0x41; BYTE $0x42; BYTE $0x43
BYTE $0x44; BYTE $0x45; BYTE $0x46; BYTE $0x47
BYTE $0x48; BYTE $0x49; BYTE $0xad; BYTE $0xf4
BYTE $0xf6; BYTE $0xf2; BYTE $0xf3; BYTE $0xf5
BYTE $0x7d; BYTE $0x4a; BYTE $0x4b; BYTE $0x4c
BYTE $0x4d; BYTE $0x4e; BYTE $0x4f; BYTE $0x50
BYTE $0x51; BYTE $0x52; BYTE $0xb9; BYTE $0xfb
BYTE $0xfc; BYTE $0xf9; BYTE $0xfa; BYTE $0xff
BYTE $0x5c; BYTE $0xf7; BYTE $0x53; BYTE $0x54
BYTE $0x55; BYTE $0x56; BYTE $0x57; BYTE $0x58
BYTE $0x59; BYTE $0x5a; BYTE $0xb2; BYTE $0xd4
BYTE $0xd6; BYTE $0xd2; BYTE $0xd3; BYTE $0xd5
BYTE $0x30; BYTE $0x31; BYTE $0x32; BYTE $0x33
BYTE $0x34; BYTE $0x35; BYTE $0x36; BYTE $0x37
BYTE $0x38; BYTE $0x39; BYTE $0xb3; BYTE $0xdb
BYTE $0xdc; BYTE $0xd9; BYTE $0xda; BYTE $0x9f
retry:
WORD $0xB9931022 // TROO 2,2,b'0001'
BVS retry
RET

View File

@@ -1,220 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build zos && s390x
package unix
import (
"sync"
)
// This file simulates epoll on z/OS using poll.
// Analogous to epoll_event on Linux.
// TODO(neeilan): Pad is because the Linux kernel expects a 96-bit struct. We never pass this to the kernel; remove?
type EpollEvent struct {
Events uint32
Fd int32
Pad int32
}
const (
EPOLLERR = 0x8
EPOLLHUP = 0x10
EPOLLIN = 0x1
EPOLLMSG = 0x400
EPOLLOUT = 0x4
EPOLLPRI = 0x2
EPOLLRDBAND = 0x80
EPOLLRDNORM = 0x40
EPOLLWRBAND = 0x200
EPOLLWRNORM = 0x100
EPOLL_CTL_ADD = 0x1
EPOLL_CTL_DEL = 0x2
EPOLL_CTL_MOD = 0x3
// The following constants are part of the epoll API, but represent
// currently unsupported functionality on z/OS.
// EPOLL_CLOEXEC = 0x80000
// EPOLLET = 0x80000000
// EPOLLONESHOT = 0x40000000
// EPOLLRDHUP = 0x2000 // Typically used with edge-triggered notis
// EPOLLEXCLUSIVE = 0x10000000 // Exclusive wake-up mode
// EPOLLWAKEUP = 0x20000000 // Relies on Linux's BLOCK_SUSPEND capability
)
// TODO(neeilan): We can eliminate these epToPoll / pToEpoll calls by using identical mask values for POLL/EPOLL
// constants where possible The lower 16 bits of epoll events (uint32) can fit any system poll event (int16).
// epToPollEvt converts epoll event field to poll equivalent.
// In epoll, Events is a 32-bit field, while poll uses 16 bits.
func epToPollEvt(events uint32) int16 {
var ep2p = map[uint32]int16{
EPOLLIN: POLLIN,
EPOLLOUT: POLLOUT,
EPOLLHUP: POLLHUP,
EPOLLPRI: POLLPRI,
EPOLLERR: POLLERR,
}
var pollEvts int16 = 0
for epEvt, pEvt := range ep2p {
if (events & epEvt) != 0 {
pollEvts |= pEvt
}
}
return pollEvts
}
// pToEpollEvt converts 16 bit poll event bitfields to 32-bit epoll event fields.
func pToEpollEvt(revents int16) uint32 {
var p2ep = map[int16]uint32{
POLLIN: EPOLLIN,
POLLOUT: EPOLLOUT,
POLLHUP: EPOLLHUP,
POLLPRI: EPOLLPRI,
POLLERR: EPOLLERR,
}
var epollEvts uint32 = 0
for pEvt, epEvt := range p2ep {
if (revents & pEvt) != 0 {
epollEvts |= epEvt
}
}
return epollEvts
}
// Per-process epoll implementation.
type epollImpl struct {
mu sync.Mutex
epfd2ep map[int]*eventPoll
nextEpfd int
}
// eventPoll holds a set of file descriptors being watched by the process. A process can have multiple epoll instances.
// On Linux, this is an in-kernel data structure accessed through a fd.
type eventPoll struct {
mu sync.Mutex
fds map[int]*EpollEvent
}
// epoll impl for this process.
var impl epollImpl = epollImpl{
epfd2ep: make(map[int]*eventPoll),
nextEpfd: 0,
}
func (e *epollImpl) epollcreate(size int) (epfd int, err error) {
e.mu.Lock()
defer e.mu.Unlock()
epfd = e.nextEpfd
e.nextEpfd++
e.epfd2ep[epfd] = &eventPoll{
fds: make(map[int]*EpollEvent),
}
return epfd, nil
}
func (e *epollImpl) epollcreate1(flag int) (fd int, err error) {
return e.epollcreate(4)
}
func (e *epollImpl) epollctl(epfd int, op int, fd int, event *EpollEvent) (err error) {
e.mu.Lock()
defer e.mu.Unlock()
ep, ok := e.epfd2ep[epfd]
if !ok {
return EBADF
}
switch op {
case EPOLL_CTL_ADD:
// TODO(neeilan): When we make epfds and fds disjoint, detect epoll
// loops here (instances watching each other) and return ELOOP.
if _, ok := ep.fds[fd]; ok {
return EEXIST
}
ep.fds[fd] = event
case EPOLL_CTL_MOD:
if _, ok := ep.fds[fd]; !ok {
return ENOENT
}
ep.fds[fd] = event
case EPOLL_CTL_DEL:
if _, ok := ep.fds[fd]; !ok {
return ENOENT
}
delete(ep.fds, fd)
}
return nil
}
// Must be called while holding ep.mu
func (ep *eventPoll) getFds() []int {
fds := make([]int, len(ep.fds))
for fd := range ep.fds {
fds = append(fds, fd)
}
return fds
}
func (e *epollImpl) epollwait(epfd int, events []EpollEvent, msec int) (n int, err error) {
e.mu.Lock() // in [rare] case of concurrent epollcreate + epollwait
ep, ok := e.epfd2ep[epfd]
if !ok {
e.mu.Unlock()
return 0, EBADF
}
pollfds := make([]PollFd, 4)
for fd, epollevt := range ep.fds {
pollfds = append(pollfds, PollFd{Fd: int32(fd), Events: epToPollEvt(epollevt.Events)})
}
e.mu.Unlock()
n, err = Poll(pollfds, msec)
if err != nil {
return n, err
}
i := 0
for _, pFd := range pollfds {
if pFd.Revents != 0 {
events[i] = EpollEvent{Fd: pFd.Fd, Events: pToEpollEvt(pFd.Revents)}
i++
}
if i == n {
break
}
}
return n, nil
}
func EpollCreate(size int) (fd int, err error) {
return impl.epollcreate(size)
}
func EpollCreate1(flag int) (fd int, err error) {
return impl.epollcreate1(flag)
}
func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
return impl.epollctl(epfd, op, fd, event)
}
// Because EpollWait mutates events, the caller is expected to coordinate
// concurrent access if calling with the same epfd from multiple goroutines.
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
return impl.epollwait(epfd, events, msec)
}

View File

@@ -1,163 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build zos && s390x
package unix
import (
"unsafe"
)
// This file simulates fstatfs on z/OS using fstatvfs and w_getmntent.
func Fstatfs(fd int, stat *Statfs_t) (err error) {
var stat_v Statvfs_t
err = Fstatvfs(fd, &stat_v)
if err == nil {
// populate stat
stat.Type = 0
stat.Bsize = stat_v.Bsize
stat.Blocks = stat_v.Blocks
stat.Bfree = stat_v.Bfree
stat.Bavail = stat_v.Bavail
stat.Files = stat_v.Files
stat.Ffree = stat_v.Ffree
stat.Fsid = stat_v.Fsid
stat.Namelen = stat_v.Namemax
stat.Frsize = stat_v.Frsize
stat.Flags = stat_v.Flag
for passn := 0; passn < 5; passn++ {
switch passn {
case 0:
err = tryGetmntent64(stat)
break
case 1:
err = tryGetmntent128(stat)
break
case 2:
err = tryGetmntent256(stat)
break
case 3:
err = tryGetmntent512(stat)
break
case 4:
err = tryGetmntent1024(stat)
break
default:
break
}
//proceed to return if: err is nil (found), err is nonnil but not ERANGE (another error occurred)
if err == nil || err != nil && err != ERANGE {
break
}
}
}
return err
}
func tryGetmntent64(stat *Statfs_t) (err error) {
var mnt_ent_buffer struct {
header W_Mnth
filesys_info [64]W_Mntent
}
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
if err != nil {
return err
}
err = ERANGE //return ERANGE if no match is found in this batch
for i := 0; i < fs_count; i++ {
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
err = nil
break
}
}
return err
}
func tryGetmntent128(stat *Statfs_t) (err error) {
var mnt_ent_buffer struct {
header W_Mnth
filesys_info [128]W_Mntent
}
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
if err != nil {
return err
}
err = ERANGE //return ERANGE if no match is found in this batch
for i := 0; i < fs_count; i++ {
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
err = nil
break
}
}
return err
}
func tryGetmntent256(stat *Statfs_t) (err error) {
var mnt_ent_buffer struct {
header W_Mnth
filesys_info [256]W_Mntent
}
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
if err != nil {
return err
}
err = ERANGE //return ERANGE if no match is found in this batch
for i := 0; i < fs_count; i++ {
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
err = nil
break
}
}
return err
}
func tryGetmntent512(stat *Statfs_t) (err error) {
var mnt_ent_buffer struct {
header W_Mnth
filesys_info [512]W_Mntent
}
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
if err != nil {
return err
}
err = ERANGE //return ERANGE if no match is found in this batch
for i := 0; i < fs_count; i++ {
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
err = nil
break
}
}
return err
}
func tryGetmntent1024(stat *Statfs_t) (err error) {
var mnt_ent_buffer struct {
header W_Mnth
filesys_info [1024]W_Mntent
}
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
if err != nil {
return err
}
err = ERANGE //return ERANGE if no match is found in this batch
for i := 0; i < fs_count; i++ {
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
err = nil
break
}
}
return err
}

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
// For Unix, get the pagesize from the runtime. // For Unix, get the pagesize from the runtime.

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build darwin //go:build darwin || zos
package unix package unix

58
vendor/golang.org/x/sys/unix/sockcmsg_zos.go generated vendored Normal file
View File

@@ -0,0 +1,58 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Socket control messages
package unix
import "unsafe"
// UnixCredentials encodes credentials into a socket control message
// for sending to another process. This can be used for
// authentication.
func UnixCredentials(ucred *Ucred) []byte {
b := make([]byte, CmsgSpace(SizeofUcred))
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
h.Level = SOL_SOCKET
h.Type = SCM_CREDENTIALS
h.SetLen(CmsgLen(SizeofUcred))
*(*Ucred)(h.data(0)) = *ucred
return b
}
// ParseUnixCredentials decodes a socket control message that contains
// credentials in a Ucred structure. To receive such a message, the
// SO_PASSCRED option must be enabled on the socket.
func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) {
if m.Header.Level != SOL_SOCKET {
return nil, EINVAL
}
if m.Header.Type != SCM_CREDENTIALS {
return nil, EINVAL
}
ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
return &ucred, nil
}
// PktInfo4 encodes Inet4Pktinfo into a socket control message of type IP_PKTINFO.
func PktInfo4(info *Inet4Pktinfo) []byte {
b := make([]byte, CmsgSpace(SizeofInet4Pktinfo))
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
h.Level = SOL_IP
h.Type = IP_PKTINFO
h.SetLen(CmsgLen(SizeofInet4Pktinfo))
*(*Inet4Pktinfo)(h.data(0)) = *info
return b
}
// PktInfo6 encodes Inet6Pktinfo into a socket control message of type IPV6_PKTINFO.
func PktInfo6(info *Inet6Pktinfo) []byte {
b := make([]byte, CmsgSpace(SizeofInet6Pktinfo))
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
h.Level = SOL_IPV6
h.Type = IPV6_PKTINFO
h.SetLen(CmsgLen(SizeofInet6Pktinfo))
*(*Inet6Pktinfo)(h.data(0)) = *info
return b
}

75
vendor/golang.org/x/sys/unix/symaddr_zos_s390x.s generated vendored Normal file
View File

@@ -0,0 +1,75 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build zos && s390x && gc
#include "textflag.h"
// provide the address of function variable to be fixed up.
TEXT ·getPipe2Addr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Pipe2(SB), R8
MOVD R8, ret+0(FP)
RET
TEXT ·get_FlockAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Flock(SB), R8
MOVD R8, ret+0(FP)
RET
TEXT ·get_GetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Getxattr(SB), R8
MOVD R8, ret+0(FP)
RET
TEXT ·get_NanosleepAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Nanosleep(SB), R8
MOVD R8, ret+0(FP)
RET
TEXT ·get_SetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Setxattr(SB), R8
MOVD R8, ret+0(FP)
RET
TEXT ·get_Wait4Addr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Wait4(SB), R8
MOVD R8, ret+0(FP)
RET
TEXT ·get_MountAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Mount(SB), R8
MOVD R8, ret+0(FP)
RET
TEXT ·get_UnmountAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Unmount(SB), R8
MOVD R8, ret+0(FP)
RET
TEXT ·get_UtimesNanoAtAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·UtimesNanoAt(SB), R8
MOVD R8, ret+0(FP)
RET
TEXT ·get_UtimesNanoAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·UtimesNano(SB), R8
MOVD R8, ret+0(FP)
RET
TEXT ·get_MkfifoatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Mkfifoat(SB), R8
MOVD R8, ret+0(FP)
RET
TEXT ·get_ChtagAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Chtag(SB), R8
MOVD R8, ret+0(FP)
RET
TEXT ·get_ReadlinkatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Readlinkat(SB), R8
MOVD R8, ret+0(FP)
RET

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build (darwin && !ios) || linux //go:build (darwin && !ios) || linux || zos
package unix package unix

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build darwin && !ios //go:build (darwin && !ios) || zos
package unix package unix

View File

@@ -491,6 +491,7 @@ const (
BPF_F_REPLACE = 0x4 BPF_F_REPLACE = 0x4
BPF_F_SLEEPABLE = 0x10 BPF_F_SLEEPABLE = 0x10
BPF_F_STRICT_ALIGNMENT = 0x1 BPF_F_STRICT_ALIGNMENT = 0x1
BPF_F_TEST_REG_INVARIANTS = 0x80
BPF_F_TEST_RND_HI32 = 0x4 BPF_F_TEST_RND_HI32 = 0x4
BPF_F_TEST_RUN_ON_CPU = 0x1 BPF_F_TEST_RUN_ON_CPU = 0x1
BPF_F_TEST_STATE_FREQ = 0x8 BPF_F_TEST_STATE_FREQ = 0x8
@@ -1697,6 +1698,7 @@ const (
KEXEC_ARCH_S390 = 0x160000 KEXEC_ARCH_S390 = 0x160000
KEXEC_ARCH_SH = 0x2a0000 KEXEC_ARCH_SH = 0x2a0000
KEXEC_ARCH_X86_64 = 0x3e0000 KEXEC_ARCH_X86_64 = 0x3e0000
KEXEC_FILE_DEBUG = 0x8
KEXEC_FILE_NO_INITRAMFS = 0x4 KEXEC_FILE_NO_INITRAMFS = 0x4
KEXEC_FILE_ON_CRASH = 0x2 KEXEC_FILE_ON_CRASH = 0x2
KEXEC_FILE_UNLOAD = 0x1 KEXEC_FILE_UNLOAD = 0x1
@@ -1898,6 +1900,7 @@ const (
MNT_DETACH = 0x2 MNT_DETACH = 0x2
MNT_EXPIRE = 0x4 MNT_EXPIRE = 0x4
MNT_FORCE = 0x1 MNT_FORCE = 0x1
MNT_ID_REQ_SIZE_VER0 = 0x18
MODULE_INIT_COMPRESSED_FILE = 0x4 MODULE_INIT_COMPRESSED_FILE = 0x4
MODULE_INIT_IGNORE_MODVERSIONS = 0x1 MODULE_INIT_IGNORE_MODVERSIONS = 0x1
MODULE_INIT_IGNORE_VERMAGIC = 0x2 MODULE_INIT_IGNORE_VERMAGIC = 0x2
@@ -2302,6 +2305,7 @@ const (
PERF_AUX_FLAG_PARTIAL = 0x4 PERF_AUX_FLAG_PARTIAL = 0x4
PERF_AUX_FLAG_PMU_FORMAT_TYPE_MASK = 0xff00 PERF_AUX_FLAG_PMU_FORMAT_TYPE_MASK = 0xff00
PERF_AUX_FLAG_TRUNCATED = 0x1 PERF_AUX_FLAG_TRUNCATED = 0x1
PERF_BRANCH_ENTRY_INFO_BITS_MAX = 0x21
PERF_BR_ARM64_DEBUG_DATA = 0x7 PERF_BR_ARM64_DEBUG_DATA = 0x7
PERF_BR_ARM64_DEBUG_EXIT = 0x5 PERF_BR_ARM64_DEBUG_EXIT = 0x5
PERF_BR_ARM64_DEBUG_HALT = 0x4 PERF_BR_ARM64_DEBUG_HALT = 0x4
@@ -3168,6 +3172,7 @@ const (
STATX_GID = 0x10 STATX_GID = 0x10
STATX_INO = 0x100 STATX_INO = 0x100
STATX_MNT_ID = 0x1000 STATX_MNT_ID = 0x1000
STATX_MNT_ID_UNIQUE = 0x4000
STATX_MODE = 0x2 STATX_MODE = 0x2
STATX_MTIME = 0x40 STATX_MTIME = 0x40
STATX_NLINK = 0x4 STATX_NLINK = 0x4
@@ -3562,12 +3567,16 @@ const (
XDP_RX_RING = 0x2 XDP_RX_RING = 0x2
XDP_SHARED_UMEM = 0x1 XDP_SHARED_UMEM = 0x1
XDP_STATISTICS = 0x7 XDP_STATISTICS = 0x7
XDP_TXMD_FLAGS_CHECKSUM = 0x2
XDP_TXMD_FLAGS_TIMESTAMP = 0x1
XDP_TX_METADATA = 0x2
XDP_TX_RING = 0x3 XDP_TX_RING = 0x3
XDP_UMEM_COMPLETION_RING = 0x6 XDP_UMEM_COMPLETION_RING = 0x6
XDP_UMEM_FILL_RING = 0x5 XDP_UMEM_FILL_RING = 0x5
XDP_UMEM_PGOFF_COMPLETION_RING = 0x180000000 XDP_UMEM_PGOFF_COMPLETION_RING = 0x180000000
XDP_UMEM_PGOFF_FILL_RING = 0x100000000 XDP_UMEM_PGOFF_FILL_RING = 0x100000000
XDP_UMEM_REG = 0x4 XDP_UMEM_REG = 0x4
XDP_UMEM_TX_SW_CSUM = 0x2
XDP_UMEM_UNALIGNED_CHUNK_FLAG = 0x1 XDP_UMEM_UNALIGNED_CHUNK_FLAG = 0x1
XDP_USE_NEED_WAKEUP = 0x8 XDP_USE_NEED_WAKEUP = 0x8
XDP_USE_SG = 0x10 XDP_USE_SG = 0x10

View File

@@ -11,16 +11,41 @@ package unix
const ( const (
BRKINT = 0x0001 BRKINT = 0x0001
CLOCAL = 0x1
CLOCK_MONOTONIC = 0x1 CLOCK_MONOTONIC = 0x1
CLOCK_PROCESS_CPUTIME_ID = 0x2 CLOCK_PROCESS_CPUTIME_ID = 0x2
CLOCK_REALTIME = 0x0 CLOCK_REALTIME = 0x0
CLOCK_THREAD_CPUTIME_ID = 0x3 CLOCK_THREAD_CPUTIME_ID = 0x3
CLONE_NEWIPC = 0x08000000
CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x00020000
CLONE_NEWPID = 0x20000000
CLONE_NEWUTS = 0x04000000
CLONE_PARENT = 0x00008000
CS8 = 0x0030 CS8 = 0x0030
CSIZE = 0x0030 CSIZE = 0x0030
ECHO = 0x00000008 ECHO = 0x00000008
ECHONL = 0x00000001 ECHONL = 0x00000001
EFD_SEMAPHORE = 0x00002000
EFD_CLOEXEC = 0x00001000
EFD_NONBLOCK = 0x00000004
EPOLL_CLOEXEC = 0x00001000
EPOLL_CTL_ADD = 0
EPOLL_CTL_MOD = 1
EPOLL_CTL_DEL = 2
EPOLLRDNORM = 0x0001
EPOLLRDBAND = 0x0002
EPOLLIN = 0x0003
EPOLLOUT = 0x0004
EPOLLWRBAND = 0x0008
EPOLLPRI = 0x0010
EPOLLERR = 0x0020
EPOLLHUP = 0x0040
EPOLLEXCLUSIVE = 0x20000000
EPOLLONESHOT = 0x40000000
FD_CLOEXEC = 0x01 FD_CLOEXEC = 0x01
FD_CLOFORK = 0x02 FD_CLOFORK = 0x02
FD_SETSIZE = 0x800
FNDELAY = 0x04 FNDELAY = 0x04
F_CLOSFD = 9 F_CLOSFD = 9
F_CONTROL_CVT = 13 F_CONTROL_CVT = 13
@@ -45,6 +70,39 @@ const (
FSTYPE_NFS = 0xd5 //"N" FSTYPE_NFS = 0xd5 //"N"
FSTYPE_TFS = 0xe3 //"T" FSTYPE_TFS = 0xe3 //"T"
FSTYPE_AUTOMOUNT = 0xc1 //"A" FSTYPE_AUTOMOUNT = 0xc1 //"A"
GRND_NONBLOCK = 1
GRND_RANDOM = 2
HUPCL = 0x0100 // Hang up on last close
IN_CLOEXEC = 0x00001000
IN_NONBLOCK = 0x00000004
IN_ACCESS = 0x00000001
IN_MODIFY = 0x00000002
IN_ATTRIB = 0x00000004
IN_CLOSE_WRITE = 0x00000008
IN_CLOSE_NOWRITE = 0x00000010
IN_OPEN = 0x00000020
IN_MOVED_FROM = 0x00000040
IN_MOVED_TO = 0x00000080
IN_CREATE = 0x00000100
IN_DELETE = 0x00000200
IN_DELETE_SELF = 0x00000400
IN_MOVE_SELF = 0x00000800
IN_UNMOUNT = 0x00002000
IN_Q_OVERFLOW = 0x00004000
IN_IGNORED = 0x00008000
IN_CLOSE = (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
IN_MOVE = (IN_MOVED_FROM | IN_MOVED_TO)
IN_ALL_EVENTS = (IN_ACCESS | IN_MODIFY | IN_ATTRIB |
IN_CLOSE | IN_OPEN | IN_MOVE |
IN_CREATE | IN_DELETE | IN_DELETE_SELF |
IN_MOVE_SELF)
IN_ONLYDIR = 0x01000000
IN_DONT_FOLLOW = 0x02000000
IN_EXCL_UNLINK = 0x04000000
IN_MASK_CREATE = 0x10000000
IN_MASK_ADD = 0x20000000
IN_ISDIR = 0x40000000
IN_ONESHOT = 0x80000000
IP6F_MORE_FRAG = 0x0001 IP6F_MORE_FRAG = 0x0001
IP6F_OFF_MASK = 0xfff8 IP6F_OFF_MASK = 0xfff8
IP6F_RESERVED_MASK = 0x0006 IP6F_RESERVED_MASK = 0x0006
@@ -152,10 +210,18 @@ const (
IP_PKTINFO = 101 IP_PKTINFO = 101
IP_RECVPKTINFO = 102 IP_RECVPKTINFO = 102
IP_TOS = 2 IP_TOS = 2
IP_TTL = 3 IP_TTL = 14
IP_UNBLOCK_SOURCE = 11 IP_UNBLOCK_SOURCE = 11
ICMP6_FILTER = 1
MCAST_INCLUDE = 0
MCAST_EXCLUDE = 1
MCAST_JOIN_GROUP = 40
MCAST_LEAVE_GROUP = 41
MCAST_JOIN_SOURCE_GROUP = 42
MCAST_LEAVE_SOURCE_GROUP = 43
MCAST_BLOCK_SOURCE = 44
MCAST_UNBLOCK_SOURCE = 46
ICANON = 0x0010 ICANON = 0x0010
ICMP6_FILTER = 0x26
ICRNL = 0x0002 ICRNL = 0x0002
IEXTEN = 0x0020 IEXTEN = 0x0020
IGNBRK = 0x0004 IGNBRK = 0x0004
@@ -165,10 +231,10 @@ const (
ISTRIP = 0x0080 ISTRIP = 0x0080
IXON = 0x0200 IXON = 0x0200
IXOFF = 0x0100 IXOFF = 0x0100
LOCK_SH = 0x1 // Not exist on zOS LOCK_SH = 0x1
LOCK_EX = 0x2 // Not exist on zOS LOCK_EX = 0x2
LOCK_NB = 0x4 // Not exist on zOS LOCK_NB = 0x4
LOCK_UN = 0x8 // Not exist on zOS LOCK_UN = 0x8
POLLIN = 0x0003 POLLIN = 0x0003
POLLOUT = 0x0004 POLLOUT = 0x0004
POLLPRI = 0x0010 POLLPRI = 0x0010
@@ -182,15 +248,29 @@ const (
MAP_PRIVATE = 0x1 // changes are private MAP_PRIVATE = 0x1 // changes are private
MAP_SHARED = 0x2 // changes are shared MAP_SHARED = 0x2 // changes are shared
MAP_FIXED = 0x4 // place exactly MAP_FIXED = 0x4 // place exactly
MCAST_JOIN_GROUP = 40 __MAP_MEGA = 0x8
MCAST_LEAVE_GROUP = 41 __MAP_64 = 0x10
MCAST_JOIN_SOURCE_GROUP = 42 MAP_ANON = 0x20
MCAST_LEAVE_SOURCE_GROUP = 43 MAP_ANONYMOUS = 0x20
MCAST_BLOCK_SOURCE = 44
MCAST_UNBLOCK_SOURCE = 45
MS_SYNC = 0x1 // msync - synchronous writes MS_SYNC = 0x1 // msync - synchronous writes
MS_ASYNC = 0x2 // asynchronous writes MS_ASYNC = 0x2 // asynchronous writes
MS_INVALIDATE = 0x4 // invalidate mappings MS_INVALIDATE = 0x4 // invalidate mappings
MS_BIND = 0x00001000
MS_MOVE = 0x00002000
MS_NOSUID = 0x00000002
MS_PRIVATE = 0x00040000
MS_REC = 0x00004000
MS_REMOUNT = 0x00008000
MS_RDONLY = 0x00000001
MS_UNBINDABLE = 0x00020000
MNT_DETACH = 0x00000004
ZOSDSFS_SUPER_MAGIC = 0x44534653 // zOS DSFS
NFS_SUPER_MAGIC = 0x6969 // NFS
NSFS_MAGIC = 0x6e736673 // PROCNS
PROC_SUPER_MAGIC = 0x9fa0 // proc FS
ZOSTFS_SUPER_MAGIC = 0x544653 // zOS TFS
ZOSUFS_SUPER_MAGIC = 0x554653 // zOS UFS
ZOSZFS_SUPER_MAGIC = 0x5A4653 // zOS ZFS
MTM_RDONLY = 0x80000000 MTM_RDONLY = 0x80000000
MTM_RDWR = 0x40000000 MTM_RDWR = 0x40000000
MTM_UMOUNT = 0x10000000 MTM_UMOUNT = 0x10000000
@@ -205,13 +285,20 @@ const (
MTM_REMOUNT = 0x00000100 MTM_REMOUNT = 0x00000100
MTM_NOSECURITY = 0x00000080 MTM_NOSECURITY = 0x00000080
NFDBITS = 0x20 NFDBITS = 0x20
ONLRET = 0x0020 // NL performs CR function
O_ACCMODE = 0x03 O_ACCMODE = 0x03
O_APPEND = 0x08 O_APPEND = 0x08
O_ASYNCSIG = 0x0200 O_ASYNCSIG = 0x0200
O_CREAT = 0x80 O_CREAT = 0x80
O_DIRECT = 0x00002000
O_NOFOLLOW = 0x00004000
O_DIRECTORY = 0x00008000
O_PATH = 0x00080000
O_CLOEXEC = 0x00001000
O_EXCL = 0x40 O_EXCL = 0x40
O_GETFL = 0x0F O_GETFL = 0x0F
O_LARGEFILE = 0x0400 O_LARGEFILE = 0x0400
O_NDELAY = 0x4
O_NONBLOCK = 0x04 O_NONBLOCK = 0x04
O_RDONLY = 0x02 O_RDONLY = 0x02
O_RDWR = 0x03 O_RDWR = 0x03
@@ -248,6 +335,7 @@ const (
AF_IUCV = 17 AF_IUCV = 17
AF_LAT = 14 AF_LAT = 14
AF_LINK = 18 AF_LINK = 18
AF_LOCAL = AF_UNIX // AF_LOCAL is an alias for AF_UNIX
AF_MAX = 30 AF_MAX = 30
AF_NBS = 7 AF_NBS = 7
AF_NDD = 23 AF_NDD = 23
@@ -285,15 +373,33 @@ const (
RLIMIT_AS = 5 RLIMIT_AS = 5
RLIMIT_NOFILE = 6 RLIMIT_NOFILE = 6
RLIMIT_MEMLIMIT = 7 RLIMIT_MEMLIMIT = 7
RLIMIT_MEMLOCK = 0x8
RLIM_INFINITY = 2147483647 RLIM_INFINITY = 2147483647
SCHED_FIFO = 0x2
SCM_CREDENTIALS = 0x2
SCM_RIGHTS = 0x01 SCM_RIGHTS = 0x01
SF_CLOSE = 0x00000002 SF_CLOSE = 0x00000002
SF_REUSE = 0x00000001 SF_REUSE = 0x00000001
SHM_RND = 0x2
SHM_RDONLY = 0x1
SHMLBA = 0x1000
IPC_STAT = 0x3
IPC_SET = 0x2
IPC_RMID = 0x1
IPC_PRIVATE = 0x0
IPC_CREAT = 0x1000000
__IPC_MEGA = 0x4000000
__IPC_SHAREAS = 0x20000000
__IPC_BELOWBAR = 0x10000000
IPC_EXCL = 0x2000000
__IPC_GIGA = 0x8000000
SHUT_RD = 0 SHUT_RD = 0
SHUT_RDWR = 2 SHUT_RDWR = 2
SHUT_WR = 1 SHUT_WR = 1
SOCK_CLOEXEC = 0x00001000
SOCK_CONN_DGRAM = 6 SOCK_CONN_DGRAM = 6
SOCK_DGRAM = 2 SOCK_DGRAM = 2
SOCK_NONBLOCK = 0x800
SOCK_RAW = 3 SOCK_RAW = 3
SOCK_RDM = 4 SOCK_RDM = 4
SOCK_SEQPACKET = 5 SOCK_SEQPACKET = 5
@@ -378,8 +484,6 @@ const (
S_IFMST = 0x00FF0000 S_IFMST = 0x00FF0000
TCP_KEEPALIVE = 0x8 TCP_KEEPALIVE = 0x8
TCP_NODELAY = 0x1 TCP_NODELAY = 0x1
TCP_INFO = 0xb
TCP_USER_TIMEOUT = 0x1
TIOCGWINSZ = 0x4008a368 TIOCGWINSZ = 0x4008a368
TIOCSWINSZ = 0x8008a367 TIOCSWINSZ = 0x8008a367
TIOCSBRK = 0x2000a77b TIOCSBRK = 0x2000a77b
@@ -427,7 +531,10 @@ const (
VSUSP = 9 VSUSP = 9
VTIME = 10 VTIME = 10
WCONTINUED = 0x4 WCONTINUED = 0x4
WEXITED = 0x8
WNOHANG = 0x1 WNOHANG = 0x1
WNOWAIT = 0x20
WSTOPPED = 0x10
WUNTRACED = 0x2 WUNTRACED = 0x2
_BPX_SWAP = 1 _BPX_SWAP = 1
_BPX_NONSWAP = 2 _BPX_NONSWAP = 2
@@ -452,8 +559,28 @@ const (
MADV_FREE = 15 // for Linux compatibility -- no zos semantics MADV_FREE = 15 // for Linux compatibility -- no zos semantics
MADV_WIPEONFORK = 16 // for Linux compatibility -- no zos semantics MADV_WIPEONFORK = 16 // for Linux compatibility -- no zos semantics
MADV_KEEPONFORK = 17 // for Linux compatibility -- no zos semantics MADV_KEEPONFORK = 17 // for Linux compatibility -- no zos semantics
AT_SYMLINK_NOFOLLOW = 1 // for Unix compatibility -- no zos semantics AT_SYMLINK_FOLLOW = 0x400
AT_FDCWD = 2 // for Unix compatibility -- no zos semantics AT_SYMLINK_NOFOLLOW = 0x100
XATTR_CREATE = 0x1
XATTR_REPLACE = 0x2
P_PID = 0
P_PGID = 1
P_ALL = 2
PR_SET_NAME = 15
PR_GET_NAME = 16
PR_SET_NO_NEW_PRIVS = 38
PR_GET_NO_NEW_PRIVS = 39
PR_SET_DUMPABLE = 4
PR_GET_DUMPABLE = 3
PR_SET_PDEATHSIG = 1
PR_GET_PDEATHSIG = 2
PR_SET_CHILD_SUBREAPER = 36
PR_GET_CHILD_SUBREAPER = 37
AT_FDCWD = -100
AT_EACCESS = 0x200
AT_EMPTY_PATH = 0x1000
AT_REMOVEDIR = 0x200
RENAME_NOREPLACE = 1 << 0
) )
const ( const (
@@ -476,6 +603,7 @@ const (
EMLINK = Errno(125) EMLINK = Errno(125)
ENAMETOOLONG = Errno(126) ENAMETOOLONG = Errno(126)
ENFILE = Errno(127) ENFILE = Errno(127)
ENOATTR = Errno(265)
ENODEV = Errno(128) ENODEV = Errno(128)
ENOENT = Errno(129) ENOENT = Errno(129)
ENOEXEC = Errno(130) ENOEXEC = Errno(130)
@@ -700,7 +828,7 @@ var errorList = [...]struct {
{145, "EDC5145I", "The parameter list is too long, or the message to receive was too large for the buffer."}, {145, "EDC5145I", "The parameter list is too long, or the message to receive was too large for the buffer."},
{146, "EDC5146I", "Too many levels of symbolic links."}, {146, "EDC5146I", "Too many levels of symbolic links."},
{147, "EDC5147I", "Illegal byte sequence."}, {147, "EDC5147I", "Illegal byte sequence."},
{148, "", ""}, {148, "EDC5148I", "The named attribute or data not available."},
{149, "EDC5149I", "Value Overflow Error."}, {149, "EDC5149I", "Value Overflow Error."},
{150, "EDC5150I", "UNIX System Services is not active."}, {150, "EDC5150I", "UNIX System Services is not active."},
{151, "EDC5151I", "Dynamic allocation error."}, {151, "EDC5151I", "Dynamic allocation error."},
@@ -743,6 +871,7 @@ var errorList = [...]struct {
{259, "EDC5259I", "A CUN_RS_NO_CONVERSION error was issued by Unicode Services."}, {259, "EDC5259I", "A CUN_RS_NO_CONVERSION error was issued by Unicode Services."},
{260, "EDC5260I", "A CUN_RS_TABLE_NOT_ALIGNED error was issued by Unicode Services."}, {260, "EDC5260I", "A CUN_RS_TABLE_NOT_ALIGNED error was issued by Unicode Services."},
{262, "EDC5262I", "An iconv() function encountered an unexpected error while using Unicode Services."}, {262, "EDC5262I", "An iconv() function encountered an unexpected error while using Unicode Services."},
{265, "EDC5265I", "The named attribute not available."},
{1000, "EDC8000I", "A bad socket-call constant was found in the IUCV header."}, {1000, "EDC8000I", "A bad socket-call constant was found in the IUCV header."},
{1001, "EDC8001I", "An error was found in the IUCV header."}, {1001, "EDC8001I", "An error was found in the IUCV header."},
{1002, "EDC8002I", "A socket descriptor is out of range."}, {1002, "EDC8002I", "A socket descriptor is out of range."},

364
vendor/golang.org/x/sys/unix/zsymaddr_zos_s390x.s generated vendored Normal file
View File

@@ -0,0 +1,364 @@
// go run mksyscall_zos_s390x.go -o_sysnum zsysnum_zos_s390x.go -o_syscall zsyscall_zos_s390x.go -i_syscall syscall_zos_s390x.go -o_asm zsymaddr_zos_s390x.s
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build zos && s390x
#include "textflag.h"
// provide the address of function variable to be fixed up.
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_FlistxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Flistxattr(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_FremovexattrAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Fremovexattr(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_FgetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Fgetxattr(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_FsetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Fsetxattr(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_accept4Addr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·accept4(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_RemovexattrAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Removexattr(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_Dup3Addr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Dup3(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_DirfdAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Dirfd(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_EpollCreateAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·EpollCreate(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_EpollCreate1Addr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·EpollCreate1(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_EpollCtlAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·EpollCtl(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_EpollPwaitAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·EpollPwait(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_EpollWaitAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·EpollWait(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_EventfdAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Eventfd(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_FaccessatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Faccessat(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_FchmodatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Fchmodat(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_FchownatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Fchownat(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_FdatasyncAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Fdatasync(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_fstatatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·fstatat(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_LgetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Lgetxattr(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_LsetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Lsetxattr(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_FstatfsAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Fstatfs(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_FutimesAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Futimes(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_FutimesatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Futimesat(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_GetrandomAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Getrandom(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_InotifyInitAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·InotifyInit(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_InotifyInit1Addr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·InotifyInit1(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_InotifyAddWatchAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·InotifyAddWatch(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_InotifyRmWatchAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·InotifyRmWatch(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_ListxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Listxattr(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_LlistxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Llistxattr(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_LremovexattrAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Lremovexattr(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_LutimesAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Lutimes(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_StatfsAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Statfs(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_SyncfsAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Syncfs(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_UnshareAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Unshare(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_LinkatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Linkat(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_MkdiratAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Mkdirat(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_MknodatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Mknodat(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_PivotRootAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·PivotRoot(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_PrctlAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Prctl(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_PrlimitAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Prlimit(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_RenameatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Renameat(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_Renameat2Addr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Renameat2(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_SethostnameAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Sethostname(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_SetnsAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Setns(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_SymlinkatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Symlinkat(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_UnlinkatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·Unlinkat(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_openatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·openat(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_openat2Addr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·openat2(SB), R8
MOVD R8, ret+0(FP)
RET
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
TEXT ·get_utimensatAddr(SB), NOSPLIT|NOFRAME, $0-8
MOVD $·utimensat(SB), R8
MOVD R8, ret+0(FP)
RET

File diff suppressed because it is too large Load Diff

View File

@@ -452,4 +452,9 @@ const (
SYS_FUTEX_WAKE = 454 SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455 SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456 SYS_FUTEX_REQUEUE = 456
SYS_STATMOUNT = 457
SYS_LISTMOUNT = 458
SYS_LSM_GET_SELF_ATTR = 459
SYS_LSM_SET_SELF_ATTR = 460
SYS_LSM_LIST_MODULES = 461
) )

View File

@@ -374,4 +374,9 @@ const (
SYS_FUTEX_WAKE = 454 SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455 SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456 SYS_FUTEX_REQUEUE = 456
SYS_STATMOUNT = 457
SYS_LISTMOUNT = 458
SYS_LSM_GET_SELF_ATTR = 459
SYS_LSM_SET_SELF_ATTR = 460
SYS_LSM_LIST_MODULES = 461
) )

View File

@@ -416,4 +416,9 @@ const (
SYS_FUTEX_WAKE = 454 SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455 SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456 SYS_FUTEX_REQUEUE = 456
SYS_STATMOUNT = 457
SYS_LISTMOUNT = 458
SYS_LSM_GET_SELF_ATTR = 459
SYS_LSM_SET_SELF_ATTR = 460
SYS_LSM_LIST_MODULES = 461
) )

View File

@@ -319,4 +319,9 @@ const (
SYS_FUTEX_WAKE = 454 SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455 SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456 SYS_FUTEX_REQUEUE = 456
SYS_STATMOUNT = 457
SYS_LISTMOUNT = 458
SYS_LSM_GET_SELF_ATTR = 459
SYS_LSM_SET_SELF_ATTR = 460
SYS_LSM_LIST_MODULES = 461
) )

View File

@@ -313,4 +313,9 @@ const (
SYS_FUTEX_WAKE = 454 SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455 SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456 SYS_FUTEX_REQUEUE = 456
SYS_STATMOUNT = 457
SYS_LISTMOUNT = 458
SYS_LSM_GET_SELF_ATTR = 459
SYS_LSM_SET_SELF_ATTR = 460
SYS_LSM_LIST_MODULES = 461
) )

View File

@@ -436,4 +436,9 @@ const (
SYS_FUTEX_WAKE = 4454 SYS_FUTEX_WAKE = 4454
SYS_FUTEX_WAIT = 4455 SYS_FUTEX_WAIT = 4455
SYS_FUTEX_REQUEUE = 4456 SYS_FUTEX_REQUEUE = 4456
SYS_STATMOUNT = 4457
SYS_LISTMOUNT = 4458
SYS_LSM_GET_SELF_ATTR = 4459
SYS_LSM_SET_SELF_ATTR = 4460
SYS_LSM_LIST_MODULES = 4461
) )

View File

@@ -366,4 +366,9 @@ const (
SYS_FUTEX_WAKE = 5454 SYS_FUTEX_WAKE = 5454
SYS_FUTEX_WAIT = 5455 SYS_FUTEX_WAIT = 5455
SYS_FUTEX_REQUEUE = 5456 SYS_FUTEX_REQUEUE = 5456
SYS_STATMOUNT = 5457
SYS_LISTMOUNT = 5458
SYS_LSM_GET_SELF_ATTR = 5459
SYS_LSM_SET_SELF_ATTR = 5460
SYS_LSM_LIST_MODULES = 5461
) )

View File

@@ -366,4 +366,9 @@ const (
SYS_FUTEX_WAKE = 5454 SYS_FUTEX_WAKE = 5454
SYS_FUTEX_WAIT = 5455 SYS_FUTEX_WAIT = 5455
SYS_FUTEX_REQUEUE = 5456 SYS_FUTEX_REQUEUE = 5456
SYS_STATMOUNT = 5457
SYS_LISTMOUNT = 5458
SYS_LSM_GET_SELF_ATTR = 5459
SYS_LSM_SET_SELF_ATTR = 5460
SYS_LSM_LIST_MODULES = 5461
) )

View File

@@ -436,4 +436,9 @@ const (
SYS_FUTEX_WAKE = 4454 SYS_FUTEX_WAKE = 4454
SYS_FUTEX_WAIT = 4455 SYS_FUTEX_WAIT = 4455
SYS_FUTEX_REQUEUE = 4456 SYS_FUTEX_REQUEUE = 4456
SYS_STATMOUNT = 4457
SYS_LISTMOUNT = 4458
SYS_LSM_GET_SELF_ATTR = 4459
SYS_LSM_SET_SELF_ATTR = 4460
SYS_LSM_LIST_MODULES = 4461
) )

View File

@@ -443,4 +443,9 @@ const (
SYS_FUTEX_WAKE = 454 SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455 SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456 SYS_FUTEX_REQUEUE = 456
SYS_STATMOUNT = 457
SYS_LISTMOUNT = 458
SYS_LSM_GET_SELF_ATTR = 459
SYS_LSM_SET_SELF_ATTR = 460
SYS_LSM_LIST_MODULES = 461
) )

View File

@@ -415,4 +415,9 @@ const (
SYS_FUTEX_WAKE = 454 SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455 SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456 SYS_FUTEX_REQUEUE = 456
SYS_STATMOUNT = 457
SYS_LISTMOUNT = 458
SYS_LSM_GET_SELF_ATTR = 459
SYS_LSM_SET_SELF_ATTR = 460
SYS_LSM_LIST_MODULES = 461
) )

View File

@@ -415,4 +415,9 @@ const (
SYS_FUTEX_WAKE = 454 SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455 SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456 SYS_FUTEX_REQUEUE = 456
SYS_STATMOUNT = 457
SYS_LISTMOUNT = 458
SYS_LSM_GET_SELF_ATTR = 459
SYS_LSM_SET_SELF_ATTR = 460
SYS_LSM_LIST_MODULES = 461
) )

View File

@@ -320,4 +320,9 @@ const (
SYS_FUTEX_WAKE = 454 SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455 SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456 SYS_FUTEX_REQUEUE = 456
SYS_STATMOUNT = 457
SYS_LISTMOUNT = 458
SYS_LSM_GET_SELF_ATTR = 459
SYS_LSM_SET_SELF_ATTR = 460
SYS_LSM_LIST_MODULES = 461
) )

View File

@@ -381,4 +381,9 @@ const (
SYS_FUTEX_WAKE = 454 SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455 SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456 SYS_FUTEX_REQUEUE = 456
SYS_STATMOUNT = 457
SYS_LISTMOUNT = 458
SYS_LSM_GET_SELF_ATTR = 459
SYS_LSM_SET_SELF_ATTR = 460
SYS_LSM_LIST_MODULES = 461
) )

View File

@@ -394,4 +394,9 @@ const (
SYS_FUTEX_WAKE = 454 SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455 SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456 SYS_FUTEX_REQUEUE = 456
SYS_STATMOUNT = 457
SYS_LISTMOUNT = 458
SYS_LSM_GET_SELF_ATTR = 459
SYS_LSM_SET_SELF_ATTR = 460
SYS_LSM_LIST_MODULES = 461
) )

File diff suppressed because it is too large Load Diff

View File

@@ -1178,7 +1178,8 @@ const (
PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT = 0x10 PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT = 0x10
PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT = 0x11 PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT = 0x11
PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT = 0x12 PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT = 0x12
PERF_SAMPLE_BRANCH_MAX_SHIFT = 0x13 PERF_SAMPLE_BRANCH_COUNTERS = 0x80000
PERF_SAMPLE_BRANCH_MAX_SHIFT = 0x14
PERF_SAMPLE_BRANCH_USER = 0x1 PERF_SAMPLE_BRANCH_USER = 0x1
PERF_SAMPLE_BRANCH_KERNEL = 0x2 PERF_SAMPLE_BRANCH_KERNEL = 0x2
PERF_SAMPLE_BRANCH_HV = 0x4 PERF_SAMPLE_BRANCH_HV = 0x4
@@ -1198,7 +1199,7 @@ const (
PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000
PERF_SAMPLE_BRANCH_HW_INDEX = 0x20000 PERF_SAMPLE_BRANCH_HW_INDEX = 0x20000
PERF_SAMPLE_BRANCH_PRIV_SAVE = 0x40000 PERF_SAMPLE_BRANCH_PRIV_SAVE = 0x40000
PERF_SAMPLE_BRANCH_MAX = 0x80000 PERF_SAMPLE_BRANCH_MAX = 0x100000
PERF_BR_UNKNOWN = 0x0 PERF_BR_UNKNOWN = 0x0
PERF_BR_COND = 0x1 PERF_BR_COND = 0x1
PERF_BR_UNCOND = 0x2 PERF_BR_UNCOND = 0x2
@@ -2481,6 +2482,15 @@ type XDPMmapOffsets struct {
Cr XDPRingOffset Cr XDPRingOffset
} }
type XDPUmemReg struct {
Addr uint64
Len uint64
Chunk_size uint32
Headroom uint32
Flags uint32
Tx_metadata_len uint32
}
type XDPStatistics struct { type XDPStatistics struct {
Rx_dropped uint64 Rx_dropped uint64
Rx_invalid_descs uint64 Rx_invalid_descs uint64
@@ -2935,7 +2945,7 @@ const (
BPF_TCP_LISTEN = 0xa BPF_TCP_LISTEN = 0xa
BPF_TCP_CLOSING = 0xb BPF_TCP_CLOSING = 0xb
BPF_TCP_NEW_SYN_RECV = 0xc BPF_TCP_NEW_SYN_RECV = 0xc
BPF_TCP_MAX_STATES = 0xd BPF_TCP_MAX_STATES = 0xe
TCP_BPF_IW = 0x3e9 TCP_BPF_IW = 0x3e9
TCP_BPF_SNDCWND_CLAMP = 0x3ea TCP_BPF_SNDCWND_CLAMP = 0x3ea
TCP_BPF_DELACK_MAX = 0x3eb TCP_BPF_DELACK_MAX = 0x3eb
@@ -3211,7 +3221,7 @@ const (
DEVLINK_CMD_LINECARD_NEW = 0x50 DEVLINK_CMD_LINECARD_NEW = 0x50
DEVLINK_CMD_LINECARD_DEL = 0x51 DEVLINK_CMD_LINECARD_DEL = 0x51
DEVLINK_CMD_SELFTESTS_GET = 0x52 DEVLINK_CMD_SELFTESTS_GET = 0x52
DEVLINK_CMD_MAX = 0x53 DEVLINK_CMD_MAX = 0x54
DEVLINK_PORT_TYPE_NOTSET = 0x0 DEVLINK_PORT_TYPE_NOTSET = 0x0
DEVLINK_PORT_TYPE_AUTO = 0x1 DEVLINK_PORT_TYPE_AUTO = 0x1
DEVLINK_PORT_TYPE_ETH = 0x2 DEVLINK_PORT_TYPE_ETH = 0x2
@@ -4595,7 +4605,7 @@ const (
NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_HINT = 0xc8
NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAC_MASK = 0xd7
NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca
NL80211_ATTR_MAX = 0x146 NL80211_ATTR_MAX = 0x149
NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4
NL80211_ATTR_MAX_CSA_COUNTERS = 0xce NL80211_ATTR_MAX_CSA_COUNTERS = 0xce
NL80211_ATTR_MAX_MATCH_SETS = 0x85 NL80211_ATTR_MAX_MATCH_SETS = 0x85
@@ -4861,7 +4871,7 @@ const (
NL80211_BSS_FREQUENCY_OFFSET = 0x14 NL80211_BSS_FREQUENCY_OFFSET = 0x14
NL80211_BSS_INFORMATION_ELEMENTS = 0x6 NL80211_BSS_INFORMATION_ELEMENTS = 0x6
NL80211_BSS_LAST_SEEN_BOOTTIME = 0xf NL80211_BSS_LAST_SEEN_BOOTTIME = 0xf
NL80211_BSS_MAX = 0x16 NL80211_BSS_MAX = 0x18
NL80211_BSS_MLD_ADDR = 0x16 NL80211_BSS_MLD_ADDR = 0x16
NL80211_BSS_MLO_LINK_ID = 0x15 NL80211_BSS_MLO_LINK_ID = 0x15
NL80211_BSS_PAD = 0x10 NL80211_BSS_PAD = 0x10
@@ -4965,7 +4975,7 @@ const (
NL80211_CMD_LEAVE_IBSS = 0x2c NL80211_CMD_LEAVE_IBSS = 0x2c
NL80211_CMD_LEAVE_MESH = 0x45 NL80211_CMD_LEAVE_MESH = 0x45
NL80211_CMD_LEAVE_OCB = 0x6d NL80211_CMD_LEAVE_OCB = 0x6d
NL80211_CMD_MAX = 0x9a NL80211_CMD_MAX = 0x9b
NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29 NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29
NL80211_CMD_MODIFY_LINK_STA = 0x97 NL80211_CMD_MODIFY_LINK_STA = 0x97
NL80211_CMD_NAN_MATCH = 0x78 NL80211_CMD_NAN_MATCH = 0x78
@@ -5199,7 +5209,7 @@ const (
NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf
NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe
NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf
NL80211_FREQUENCY_ATTR_MAX = 0x1c NL80211_FREQUENCY_ATTR_MAX = 0x1f
NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6
NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11
NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc

Some files were not shown because too many files have changed in this diff Show More