4 Commits
v1.1 ... go

119 changed files with 9687 additions and 5095 deletions

2
.gitignore vendored
View File

@@ -1 +1 @@
reniced
/reniced

View File

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

View File

@@ -4,8 +4,23 @@ daemon: true
# PID file for daemon.
pidfile: /var/run/reniced.pid
# Delay among iterations.
loop_delay: 5000
# Delay between process list update task consecutive runs.
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.
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
# has vacant place for new task.
nb_capacity: 30
nb_capacity: 3000
# Time to time run these commands.
periodic_process:
- ps xa
kill:
- sig: stop

View File

@@ -1,15 +1,14 @@
#!/usr/bin/env gmake -f
BUILDOPTS=-ldflags="-s -w" -a -gcflags=all=-l -trimpath
BINARY=reniced
BUILDOPTS=-ldflags="-s -w" -a -gcflags=all="-l -B" -trimpath -buildvcs=false
all: clean build
build:
go build ${BUILDOPTS} -o ${BINARY}
go build ${BUILDOPTS} -o ${BINARY} ./cmd/${BINARY}
clean:
go clean
$(RM) ${BINARY}
upgrade:
$(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
go 1.21.4
go 1.22.6
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/shirou/gopsutil/v3 v3.24.3
github.com/shirou/gopsutil/v3 v3.24.5
gopkg.in/yaml.v3 v3.0.1
)
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/lufia/plan9stats v0.0.0-20240226150601-1dcf7310316a // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // 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.8.3/go.mod h1:CmvIIGd5jKLasGI3D87qDkQxjzChdKMmnXMg3fG6M6Q=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/alitto/pond v1.9.2 h1:9Qb75z/scEZVCoSU+osVmQ0I0JOeLfdTDafrbcJ8CLs=
github.com/alitto/pond v1.9.2/go.mod h1:xQn3P/sHTYcU/1BR3i86IGIrilcrGC2LiS+E2+CJWsI=
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/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.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.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/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/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-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/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-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/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE=
github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE=
github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
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/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
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/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/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.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
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/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-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.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.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
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/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/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 {
return prio >> IOPRIO_CLASS_SHIFT

View File

@@ -1,7 +1,7 @@
//go:build linux
// +build linux
package main
package lib
import (
"fmt"
@@ -20,7 +20,7 @@ func GetIOPriority(which int, who int) (uint32, error) {
)
if e1 != 0 {
err = fmt.Errorf(fmt.Sprintf("Received error number %v", e1))
err = fmt.Errorf("received error number %w", e1)
}
return prio, err
@@ -34,18 +34,18 @@ func SetIOPriority(which int, who int, prio uint32) error {
)
if e1 != 0 {
err = fmt.Errorf(fmt.Sprintf("Received error number %v", e1))
err = fmt.Errorf("received error number %w", e1)
}
return err
}
// 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 {
currentClass, currentClassdata := PrioToClassAndClassdata(currentIOPrioLevel)
class := ioreniceClass[processName]
classdata := ioreniceClassdata[processName]
class := cnf.IoreniceClass[processName]
classdata := cnf.IoreniceClassdata[processName]
if class == currentClass && classdata == currentClassdata {
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 (
"fmt"
@@ -14,9 +14,8 @@ import (
// readConf вычиляет, от какого пользователя запущен процесс и в зависимости от результата, скармливает readConfFile тот
// или иной путь, по которому предположительно лежит конфиг.
func readConf() (Config, error) {
func (cnf *Config) ReadConf() error {
var (
cnf Config
err error
)
@@ -32,69 +31,92 @@ func readConf() (Config, error) {
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 {
if runtime.GOOS == "freebsd" {
cnf, err = readConfFile("/usr/local/etc/reniced.yaml")
err = cnf.readConfFile("/usr/local/etc/reniced.yaml")
} else {
cnf, err = readConfFile("/etc/reniced.yaml")
err = cnf.readConfFile("/etc/reniced.yaml")
}
}
return cnf, err
return err
}
// readConfFile парсит даденный конфиг в глобальную структуру, с которой работает программа.
func readConfFile(path string) (Config, error) {
var cfg Config
func (cnf *Config) readConfFile(path string) error {
fileInfo, err := os.Stat(path)
// Предполагаем, что файла либо нет, либо мы не можем его прочитать, второе надо бы логгировать, но пока забьём.
if err != nil {
return Config{}, err
return err
}
// Конфиг-файл длинноват для конфига, попробуем следующего кандидата.
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)
// Не удалось прочитать.
if err != nil {
return Config{}, err
return err
}
if err = yaml.Unmarshal(buf, &cfg); err != nil {
return Config{}, err
if err = yaml.Unmarshal(buf, &cnf); err != nil {
return err
}
if cfg.LoopDelay == 0 {
cfg.LoopDelay = 2000
log.Printf("loop_delay set to %d milliseconds", cfg.LoopDelay)
if cnf.ProcessListUpdatePeriod == 0 {
cnf.ProcessListUpdatePeriod = 5000
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")
}
if cfg.MaxWorkers == 0 {
cfg.MaxWorkers = 5
log.Printf("max_workers set to %d", cfg.MaxWorkers)
if cnf.MaxWorkers == 0 {
cnf.MaxWorkers = runtime.NumCPU()
log.Printf("max_workers set to %d", cnf.MaxWorkers)
}
if cfg.NbCapacity == 0 {
cfg.NbCapacity = 100
log.Printf("nb_capacity set to %d", cfg.NbCapacity)
if cnf.NbCapacity == 0 {
cnf.NbCapacity = 100
log.Printf("nb_capacity set to %d", cnf.NbCapacity)
}
if cfg.NbCapacity < cfg.MaxWorkers {
cfg.NbCapacity = cfg.MaxWorkers
log.Printf("nb_capacity set to same value as max_workers: %d", cfg.MaxWorkers)
if cnf.NbCapacity < cnf.MaxWorkers {
cnf.NbCapacity = cnf.MaxWorkers
log.Printf("nb_capacity set to same value as max_workers: %d", cnf.MaxWorkers)
}
// Обычный юзер не может задрать nice больше 0, только руту такое можно.
@@ -104,13 +126,13 @@ func readConfFile(path string) (Config, error) {
maxNice = -20
}
for _, v := range cfg.Prio {
for _, v := range cnf.Prio {
switch {
case len(v.Name) != 0 && (v.Nice < 20 && v.Nice > maxNice):
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)
}
}
@@ -121,7 +143,7 @@ func readConfFile(path string) (Config, error) {
}
}
for _, v := range cfg.IOPrio {
for _, v := range cnf.IOPrio {
switch {
case len(v.Name) == 0:
log.Println("Skipping empty name entry in ioprio config block")
@@ -137,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)
default:
for _, processName := range v.Name {
ioreniceClass[processName] = v.Class
ioreniceClassdata[processName] = v.Prio
cnf.IoreniceClass[processName] = v.Class
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 prio %d processes.", processName, v.Prio)
}
@@ -148,35 +170,35 @@ func readConfFile(path string) (Config, error) {
}
}
for _, v := range cfg.Kill {
for _, v := range cnf.Kill {
if len(v.Name) != 0 {
switch v.Sig {
case "kill", "stop", "term", "int", "quit", "abrt", "hup", "usr1", "usr2":
for _, procName := range v.Name {
switch v.Sig {
case "kill":
kill[procName] = syscall.SIGKILL
cnf.KillSignal[procName] = syscall.SIGKILL
case "stop":
kill[procName] = syscall.SIGSTOP
cnf.KillSignal[procName] = syscall.SIGSTOP
case "term":
kill[procName] = syscall.SIGTERM
cnf.KillSignal[procName] = syscall.SIGTERM
case "int":
kill[procName] = syscall.SIGINT
cnf.KillSignal[procName] = syscall.SIGINT
case "quit":
kill[procName] = syscall.SIGQUIT
cnf.KillSignal[procName] = syscall.SIGQUIT
case "abrt":
kill[procName] = syscall.SIGABRT
cnf.KillSignal[procName] = syscall.SIGABRT
case "hup":
kill[procName] = syscall.SIGHUP
cnf.KillSignal[procName] = syscall.SIGHUP
case "usr1":
kill[procName] = syscall.SIGUSR1
cnf.KillSignal[procName] = syscall.SIGUSR1
case "usr2":
kill[procName] = syscall.SIGUSR2
cnf.KillSignal[procName] = syscall.SIGUSR2
default:
continue
}
if cfg.Debug {
if cnf.Debug {
log.Printf(
"Add %s to list of processes that should be killed with SIG%s signal.",
procName,
@@ -192,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: */

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
- **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
// This will create a pool with 5 running worker goroutines
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
// This will create a pool that will remove workers 100ms after they become idle
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
// Custom panic handler function
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
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.
- **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.
#### 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.
- **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
// Example: create pools with different resizing strategies
eagerPool := pond.New(10, 1000, pond.Strategy(pond.Eager()))
balancedPool := pond.New(10, 1000, pond.Strategy(pond.Balanced()))
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
// This creates a pool that is stopped when myCtx is cancelled
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.
// Tasks being executed by workers will continue until completion (unless the process is terminated).
// Tasks in the queue will not be executed.
func (p *WorkerPool) Stop() {
go p.stop(false)
// This method returns a context object that is cancelled when the pool has stopped completely.
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
@@ -371,6 +377,7 @@ func (p *WorkerPool) stop(waitForQueuedTasksToComplete bool) {
p.tasksCloseOnce.Do(func() {
close(p.tasks)
})
}
// purge represents the work done by the purger goroutine
@@ -420,7 +427,7 @@ func (p *WorkerPool) maybeStartWorker(firstTask func()) bool {
}
// 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
}

View File

@@ -6,7 +6,7 @@ import (
)
// 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 firstTask != nil {
@@ -20,16 +20,43 @@ func worker(context context.Context, waitGroup *sync.WaitGroup, firstTask func()
for {
select {
case <-context.Done():
// Pool context was cancelled, exit
// Pool context was cancelled, empty tasks channel and exit
drainTasks(tasks, taskWaitGroup)
return
case task, ok := <-tasks:
if task == nil || !ok {
// We have received a signal to exit
// 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 {
// We have received a signal to exit
return
}
// We have received a task, execute it
taskExecutor(task, false)
// We have received a task, execute it
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}"
os: Visual Studio 2019
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 ./...
os: Windows Server 2012 R2
branches:
only:
@@ -37,19 +15,26 @@ branches:
- v1.1
- v1.0
matrix:
allow_failures:
- environment:
GOROOT: C:\go-x86
DOWNLOADPLATFORM: "x86"
- environment:
GOROOT: C:\go118
DOWNLOADPLATFORM: "x64"
- environment:
GOROOT: C:\go118-x86
DOWNLOADPLATFORM: "x86"
skip_tags: true
clone_folder: c:\gopath\src\github.com\go-ole\go-ole
environment:
GOPATH: c:\gopath
matrix:
- GOARCH: amd64
GOVERSION: 1.5
GOROOT: c:\go
DOWNLOADPLATFORM: "x64"
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 env
- 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
- go get -v -t ./...
- go build
- go test -v -cover ./...
# disable automatic tests
test: on
test: off
# disable deployment
deploy: off

View File

@@ -11,7 +11,6 @@ import (
var (
procCoInitialize = modole32.NewProc("CoInitialize")
procCoInitializeEx = modole32.NewProc("CoInitializeEx")
procCoInitializeSecurity = modole32.NewProc("CoInitializeSecurity")
procCoUninitialize = modole32.NewProc("CoUninitialize")
procCoCreateInstance = modole32.NewProc("CoCreateInstance")
procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
@@ -38,9 +37,6 @@ var (
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.
//
// MSDN documentation suggests that this function should not be called. Call
@@ -72,35 +68,6 @@ func coInitializeEx(coinit uint32) (err error) {
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.
//
// MSDN documentation suggests that this function should not be called. Call
@@ -129,15 +96,6 @@ func CoUninitialize() {
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.
func CoTaskMemFree(memptr uintptr) {
procCoTaskMemFree.Call(memptr)

View File

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

View File

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

View File

@@ -1,13 +1,2 @@
# plan9stats
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
pids := make([]uint32, len(names))
for i, s := range names {
if s == "trace" {
continue
}
pids[i] = up.Parse(s)
}
if err := up.err; err != nil {
if up.err != nil {
return nil, err
}
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
}
type Storage struct {
Name string
Model string
Capacity int64
}
type Interface struct {
Name string
Addr string
@@ -171,7 +177,7 @@ func ReadHost(ctx context.Context, opts ...Option) (*Host, error) {
}
h.Sysname = name
a, err := ReadStorages(ctx, opts...)
a, err := readStorages(cfg.rootdir)
if err != nil {
return nil, err
}
@@ -197,6 +203,80 @@ func readSysname(rootdir string) (string, error) {
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 {
ID int // number of interface in ipifc dir
Device string // associated physical device

View File

@@ -26,15 +26,6 @@ func (p *intParser) ParseInt64(s string, base int) int64 {
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 {
return p.err
}

View File

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

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix
package perfstat
@@ -21,13 +20,6 @@ import (
"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) {
var cpustat *C.perfstat_cpu_t
var cpu C.perfstat_id_t
@@ -104,35 +96,3 @@ func CpuUtilStat(intvl time.Duration) (*CPUUtil, error) {
u := perfstatcpuutil2cpuutil(cpuutil)
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
package perfstat

View File

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

View File

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

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix
package perfstat
@@ -8,7 +7,6 @@ package perfstat
#include <libperfstat.h>
#include <sys/proc.h>
#include <sys/dr.h>
#include "c_helpers.h"
*/
@@ -756,7 +754,7 @@ func fsinfo2filesystem(n *C.struct_fsinfo) FileSystem {
i.Device = C.GoString(n.devname)
i.MountPoint = C.GoString(n.fsname)
i.FSType = int(n.fstype)
i.Flags = uint(n.flags)
i.Flags = int(n.flags)
i.TotalBlocks = int64(n.totalblks)
i.FreeBlocks = int64(n.freeblks)
i.TotalInodes = int64(n.totalinodes)
@@ -764,56 +762,3 @@ func fsinfo2filesystem(n *C.struct_fsinfo) FileSystem {
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
package perfstat
@@ -7,13 +6,11 @@ package perfstat
#cgo LDFLAGS: -lperfstat
#include <libperfstat.h>
#include <sys/dr.h>
*/
import "C"
import (
"fmt"
"unsafe"
)
func PartitionStat() (*PartitionConfig, error) {
@@ -27,14 +24,3 @@ func PartitionStat() (*PartitionConfig, error) {
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
package perfstat

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,3 @@
//go:build aix
// +build aix
package perfstat
@@ -71,7 +70,6 @@ const (
SC_TM_VER = 59 /* Transaction Memory version, 0 - not capable */
SC_NX_CAP = 60 /* NX GZIP capable */
SC_PKS_STATE = 61 /* Platform KeyStore */
SC_MMA_VER = 62
)
/* kernel attributes */
@@ -121,7 +119,6 @@ const (
IMPL_POWER7 = 0x8000 /* 7 class CPU */
IMPL_POWER8 = 0x10000 /* 8 class CPU */
IMPL_POWER9 = 0x20000 /* 9 class CPU */
IMPL_POWER10 = 0x20000 /* 10 class CPU */
)
// Values for implementation field for IA64 Architectures
@@ -154,13 +151,11 @@ const (
PV_7 = 0x200000 /* Power PC 7 */
PV_8 = 0x300000 /* Power PC 8 */
PV_9 = 0x400000 /* Power PC 9 */
PV_10 = 0x500000 /* Power PC 10 */
PV_5_Compat = 0x0F8000 /* Power PC 5 */
PV_6_Compat = 0x108000 /* Power PC 6 */
PV_7_Compat = 0x208000 /* Power PC 7 */
PV_8_Compat = 0x308000 /* Power PC 8 */
PV_9_Compat = 0x408000 /* Power PC 9 */
PV_10_Compat = 0x508000 /* Power PC 10 */
PV_RESERVED_2 = 0x0A0000 /* source compatability */
PV_RESERVED_3 = 0x0B0000 /* source compatability */
PV_RS2 = 0x040000 /* Power RS2 */
@@ -186,21 +181,19 @@ const (
// Macros for identifying physical processor
const (
PPI4_1 = 0x35
PPI4_2 = 0x38
PPI4_3 = 0x39
PPI4_4 = 0x3C
PPI4_5 = 0x44
PPI5_1 = 0x3A
PPI5_2 = 0x3B
PPI6_1 = 0x3E
PPI7_1 = 0x3F
PPI7_2 = 0x4A
PPI8_1 = 0x4B
PPI8_2 = 0x4D
PPI9 = 0x4E
PPI9_1 = 0x4E
PPI10_1 = 0x80
PPI4_1 = 0x35
PPI4_2 = 0x38
PPI4_3 = 0x39
PPI4_4 = 0x3C
PPI4_5 = 0x44
PPI5_1 = 0x3A
PPI5_2 = 0x3B
PPI6_1 = 0x3E
PPI7_1 = 0x3F
PPI7_2 = 0x4A
PPI8_1 = 0x4B
PPI8_2 = 0x4D
PPI9 = 0x4E
)
// Macros for kernel attributes
@@ -298,32 +291,14 @@ func GetCPUImplementation() string {
return "POWER8"
case impl&IMPL_POWER9 != 0:
return "POWER9"
case impl&IMPL_POWER10 != 0:
return "Power10"
default:
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 {
impl := unix.Getsystemcfg(SC_IMPL)
if impl&IMPL_POWER10 != 0 || impl&IMPL_POWER9 != 0 {
if impl&IMPL_POWER9 != 0 {
return true
}
return false
@@ -339,7 +314,7 @@ func POWER9() bool {
func POWER8OrNewer() bool {
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 false
@@ -355,7 +330,7 @@ func POWER8() bool {
func POWER7OrNewer() bool {
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 false
@@ -444,8 +419,6 @@ func PksEnabled() bool {
func CPUMode() string {
impl := unix.Getsystemcfg(SC_VERS)
switch impl {
case PV_10, PV_10_Compat:
return "Power10"
case PV_9, PV_9_Compat:
return "POWER9"
case PV_8, PV_8_Compat:

View File

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

View File

@@ -8,7 +8,7 @@ type FileSystem struct {
Device string /* name of the mounted device */
MountPoint string /* where the device is mounted */
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 */
FreeBlocks int64 /* number of free 512 bytes block 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 */
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
package perfstat

View File

@@ -12,8 +12,57 @@ import (
)
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
var ret []TimesStat
if percpu {
return []TimesStat{}, common.ErrNotImplementedError
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
}
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 {
out, err := invoke.CommandWithContext(ctx, "sar", "-u", "10", "1")
if err != nil {
@@ -24,26 +73,28 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
return []TimesStat{}, common.ErrNotImplementedError
}
ret := TimesStat{CPU: "cpu-total"}
ct := &TimesStat{CPU: "cpu-total"}
h := strings.Fields(lines[len(lines)-3]) // headers
v := strings.Fields(lines[len(lines)-2]) // values
for i, header := range h {
if t, err := strconv.ParseFloat(v[i], 64); err == nil {
switch header {
case `%usr`:
ret.User = t
ct.User = t
case `%sys`:
ret.System = t
ct.System = t
case `%wio`:
ret.Iowait = t
ct.Iowait = t
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) {
@@ -78,6 +129,20 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
}
}
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

View File

@@ -6,7 +6,7 @@ import (
)
// 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 {
timer := time.NewTimer(interval)
select {

View File

@@ -12,7 +12,7 @@ import (
)
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
vmem, swap, err := callSVMon(ctx)
vmem, swap, err := callSVMon(ctx, true)
if err != nil {
return nil, err
}
@@ -25,7 +25,7 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
}
func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
_, swap, err := callSVMon(ctx)
_, swap, err := callSVMon(ctx, false)
if err != nil {
return nil, err
}
@@ -35,7 +35,7 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
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")
if err != nil {
return nil, nil, err
@@ -45,7 +45,7 @@ func callSVMon(ctx context.Context) (*VirtualMemoryStat, *SwapMemoryStat, error)
vmem := &VirtualMemoryStat{}
swap := &SwapMemoryStat{}
for _, line := range strings.Split(string(out), "\n") {
if strings.HasPrefix(line, "memory") {
if virt && strings.HasPrefix(line, "memory") {
p := strings.Fields(line)
if len(p) > 2 {
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 {
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)
}

View File

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

View File

@@ -24,14 +24,21 @@ func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
}
txtFound := 0
lines := strings.Split(string(out), "\n")
fallback := ""
for i := 1; i < len(lines); i++ {
if lines[i] == "ftxt" {
txtFound++
if txtFound == 1 {
fallback = lines[i-1][1:]
}
if txtFound == 2 {
return lines[i-1][1:], nil
}
}
}
if fallback != "" {
return fallback, nil
}
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) {
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) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -25,10 +25,10 @@ const (
_POSIX2_UPE = -1
)
var clktck struct {
sync.Once
v int64
}
var (
clktck int64
clktckOnce sync.Once
)
func sysconfPOSIX(name int) (int64, error) {
// 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.
switch name {
// 1003.1
case SC_ARG_MAX:
return sysctl32("kern.argmax"), nil
@@ -54,14 +55,13 @@ func sysconf(name int) (int64, error) {
}
return -1, nil
case SC_CLK_TCK:
// TODO: use sync.OnceValue once Go 1.21 is the minimal supported version
clktck.Do(func() {
clktck.v = -1
clktckOnce.Do(func() {
clktck = -1
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:
return sysctl32("kern.ngroups"), nil
case SC_JOB_CONTROL:

View File

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

View File

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

View File

@@ -9,9 +9,11 @@
#define PSALAA 1208(R0)
#define GTAB64(x) 80(x)
#define LCA64(x) 88(x)
#define SAVSTACK_ASYNC(x) 336(x) // in the LCA
#define CAA(x) 8(x)
#define EDCHPXV(x) 1016(x) // in the CAA
#define SAVSTACK_ASYNC(x) 336(x) // in the LCA
#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
#define SS_LE(x) 0(x)
@@ -19,394 +21,125 @@
#define SS_ERRNO(x) 16(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
BL addrerrno<>(SB)
MOVD $0, 0(R3)
// 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)
MOVD $0, 0(R3)
RET
// 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).
MOVW PSALAA, R8
MOVD LCA64(R8), R8
MOVW PSALAA, R8
MOVD LCA64(R8), R8
// Get __errno FuncDesc.
MOVD CAA(R8), R9
MOVD EDCHPXV(R9), R9
ADD $(0x156*16), R9
LMG 0(R9), R5, R6
MOVD CAA(R8), R9
MOVD EDCHPXV(R9), R9
ADD $(__errno), R9
LMG 0(R9), R5, R6
// Switch to saved LE stack.
MOVD SAVSTACK_ASYNC(R8), R9
MOVD 0(R9), R4
MOVD $0, 0(R9)
MOVD SAVSTACK_ASYNC(R8), R9
MOVD 0(R9), R4
MOVD $0, 0(R9)
// Call __errno function.
LE_CALL
NOPH
// Switch back to Go stack.
XOR R0, R0 // Restore R0 to $0.
MOVD R4, 0(R9) // Save stack pointer.
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:
XOR R0, R0 // Restore R0 to $0.
MOVD R4, 0(R9) // Save stack pointer.
RET
// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
TEXT ·svcCall(SB),NOSPLIT,$0
BL runtime·save_g(SB) // Save g and stack pointer
MOVW PSALAA, R8
MOVD LCA64(R8), R8
MOVD SAVSTACK_ASYNC(R8), R9
MOVD R15, 0(R9)
TEXT ·svcCall(SB), NOSPLIT, $0
BL runtime·save_g(SB) // Save g and stack pointer
MOVW PSALAA, R8
MOVD LCA64(R8), R8
MOVD SAVSTACK_ASYNC(R8), R9
MOVD R15, 0(R9)
MOVD argv+8(FP), R1 // Move function arguments into registers
MOVD dsa+16(FP), g
MOVD fnptr+0(FP), R15
MOVD argv+8(FP), R1 // Move function arguments into registers
MOVD dsa+16(FP), g
MOVD fnptr+0(FP), R15
BYTE $0x0D // Branch to function
BYTE $0xEF
BYTE $0x0D // Branch to function
BYTE $0xEF
BL runtime·load_g(SB) // Restore g and stack pointer
MOVW PSALAA, R8
MOVD LCA64(R8), R8
MOVD SAVSTACK_ASYNC(R8), R9
MOVD 0(R9), R15
BL runtime·load_g(SB) // Restore g and stack pointer
MOVW PSALAA, R8
MOVD LCA64(R8), R8
MOVD SAVSTACK_ASYNC(R8), R9
MOVD 0(R9), R15
RET
// func svcLoad(name *byte) unsafe.Pointer
TEXT ·svcLoad(SB),NOSPLIT,$0
MOVD R15, R2 // Save go stack pointer
MOVD name+0(FP), R0 // Move SVC args into registers
MOVD $0x80000000, R1
MOVD $0, R15
BYTE $0x0A // SVC 08 LOAD
BYTE $0x08
MOVW R15, R3 // Save return code from SVC
MOVD R2, R15 // Restore go stack pointer
CMP R3, $0 // Check SVC return code
BNE error
TEXT ·svcLoad(SB), NOSPLIT, $0
MOVD R15, R2 // Save go stack pointer
MOVD name+0(FP), R0 // Move SVC args into registers
MOVD $0x80000000, R1
MOVD $0, R15
SVC_LOAD
MOVW R15, R3 // Save return code from SVC
MOVD R2, R15 // Restore go stack pointer
CMP R3, $0 // Check SVC return code
BNE error
MOVD $-2, R3 // Reset last bit of entry point to zero
AND R0, R3
MOVD R3, addr+8(FP) // Return entry point returned by SVC
CMP R0, R3 // Check if last bit of entry point was set
BNE done
MOVD $-2, R3 // Reset last bit of entry point to zero
AND R0, R3
MOVD R3, ret+8(FP) // Return entry point returned by SVC
CMP R0, R3 // Check if last bit of entry point was set
BNE done
MOVD R15, R2 // Save go stack pointer
MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)
BYTE $0x0A // SVC 09 DELETE
BYTE $0x09
MOVD R2, R15 // Restore 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)
SVC_DELETE
MOVD R2, R15 // Restore go stack pointer
error:
MOVD $0, addr+8(FP) // Return 0 on failure
MOVD $0, ret+8(FP) // Return 0 on failure
done:
XOR R0, R0 // Reset r0 to 0
XOR R0, R0 // Reset r0 to 0
RET
// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
TEXT ·svcUnload(SB),NOSPLIT,$0
MOVD R15, R2 // Save go stack pointer
MOVD name+0(FP), R0 // Move SVC args into registers
MOVD addr+8(FP), R15
BYTE $0x0A // SVC 09
BYTE $0x09
XOR R0, R0 // Reset r0 to 0
MOVD R15, R1 // Save SVC return code
MOVD R2, R15 // Restore go stack pointer
MOVD R1, rc+0(FP) // Return SVC return code
TEXT ·svcUnload(SB), NOSPLIT, $0
MOVD R15, R2 // Save go stack pointer
MOVD name+0(FP), R0 // Move SVC args into registers
MOVD fnptr+8(FP), R15
SVC_DELETE
XOR R0, R0 // Reset r0 to 0
MOVD R15, R1 // Save SVC return code
MOVD R2, R15 // Restore go stack pointer
MOVD R1, ret+16(FP) // Return SVC return code
RET
// func gettid() uint64
@@ -417,7 +150,233 @@ TEXT ·gettid(SB), NOSPLIT, $0
// Get CEECAATHDID
MOVD CAA(R8), R9
MOVD 0x3D0(R9), R9
MOVD CEECAATHDID(R9), R9
MOVD R9, ret+0(FP)
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
// 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.

View File

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

View File

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

View File

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

View File

@@ -10,41 +10,99 @@
package unix
const (
BRKINT = 0x0001
CLOCK_MONOTONIC = 0x1
CLOCK_PROCESS_CPUTIME_ID = 0x2
CLOCK_REALTIME = 0x0
CLOCK_THREAD_CPUTIME_ID = 0x3
CS8 = 0x0030
CSIZE = 0x0030
ECHO = 0x00000008
ECHONL = 0x00000001
FD_CLOEXEC = 0x01
FD_CLOFORK = 0x02
FNDELAY = 0x04
F_CLOSFD = 9
F_CONTROL_CVT = 13
F_DUPFD = 0
F_DUPFD2 = 8
F_GETFD = 1
F_GETFL = 259
F_GETLK = 5
F_GETOWN = 10
F_OK = 0x0
F_RDLCK = 1
F_SETFD = 2
F_SETFL = 4
F_SETLK = 6
F_SETLKW = 7
F_SETOWN = 11
F_SETTAG = 12
F_UNLCK = 3
F_WRLCK = 2
FSTYPE_ZFS = 0xe9 //"Z"
FSTYPE_HFS = 0xc8 //"H"
FSTYPE_NFS = 0xd5 //"N"
FSTYPE_TFS = 0xe3 //"T"
FSTYPE_AUTOMOUNT = 0xc1 //"A"
BRKINT = 0x0001
CLOCAL = 0x1
CLOCK_MONOTONIC = 0x1
CLOCK_PROCESS_CPUTIME_ID = 0x2
CLOCK_REALTIME = 0x0
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
CSIZE = 0x0030
ECHO = 0x00000008
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_CLOFORK = 0x02
FD_SETSIZE = 0x800
FNDELAY = 0x04
F_CLOSFD = 9
F_CONTROL_CVT = 13
F_DUPFD = 0
F_DUPFD2 = 8
F_GETFD = 1
F_GETFL = 259
F_GETLK = 5
F_GETOWN = 10
F_OK = 0x0
F_RDLCK = 1
F_SETFD = 2
F_SETFL = 4
F_SETLK = 6
F_SETLKW = 7
F_SETOWN = 11
F_SETTAG = 12
F_UNLCK = 3
F_WRLCK = 2
FSTYPE_ZFS = 0xe9 //"Z"
FSTYPE_HFS = 0xc8 //"H"
FSTYPE_NFS = 0xd5 //"N"
FSTYPE_TFS = 0xe3 //"T"
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_OFF_MASK = 0xfff8
IP6F_RESERVED_MASK = 0x0006
@@ -152,10 +210,18 @@ const (
IP_PKTINFO = 101
IP_RECVPKTINFO = 102
IP_TOS = 2
IP_TTL = 3
IP_TTL = 14
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
ICMP6_FILTER = 0x26
ICRNL = 0x0002
IEXTEN = 0x0020
IGNBRK = 0x0004
@@ -165,10 +231,10 @@ const (
ISTRIP = 0x0080
IXON = 0x0200
IXOFF = 0x0100
LOCK_SH = 0x1 // Not exist on zOS
LOCK_EX = 0x2 // Not exist on zOS
LOCK_NB = 0x4 // Not exist on zOS
LOCK_UN = 0x8 // Not exist on zOS
LOCK_SH = 0x1
LOCK_EX = 0x2
LOCK_NB = 0x4
LOCK_UN = 0x8
POLLIN = 0x0003
POLLOUT = 0x0004
POLLPRI = 0x0010
@@ -182,15 +248,29 @@ const (
MAP_PRIVATE = 0x1 // changes are private
MAP_SHARED = 0x2 // changes are shared
MAP_FIXED = 0x4 // place exactly
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 = 45
__MAP_MEGA = 0x8
__MAP_64 = 0x10
MAP_ANON = 0x20
MAP_ANONYMOUS = 0x20
MS_SYNC = 0x1 // msync - synchronous writes
MS_ASYNC = 0x2 // asynchronous writes
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_RDWR = 0x40000000
MTM_UMOUNT = 0x10000000
@@ -205,13 +285,20 @@ const (
MTM_REMOUNT = 0x00000100
MTM_NOSECURITY = 0x00000080
NFDBITS = 0x20
ONLRET = 0x0020 // NL performs CR function
O_ACCMODE = 0x03
O_APPEND = 0x08
O_ASYNCSIG = 0x0200
O_CREAT = 0x80
O_DIRECT = 0x00002000
O_NOFOLLOW = 0x00004000
O_DIRECTORY = 0x00008000
O_PATH = 0x00080000
O_CLOEXEC = 0x00001000
O_EXCL = 0x40
O_GETFL = 0x0F
O_LARGEFILE = 0x0400
O_NDELAY = 0x4
O_NONBLOCK = 0x04
O_RDONLY = 0x02
O_RDWR = 0x03
@@ -248,6 +335,7 @@ const (
AF_IUCV = 17
AF_LAT = 14
AF_LINK = 18
AF_LOCAL = AF_UNIX // AF_LOCAL is an alias for AF_UNIX
AF_MAX = 30
AF_NBS = 7
AF_NDD = 23
@@ -285,15 +373,33 @@ const (
RLIMIT_AS = 5
RLIMIT_NOFILE = 6
RLIMIT_MEMLIMIT = 7
RLIMIT_MEMLOCK = 0x8
RLIM_INFINITY = 2147483647
SCHED_FIFO = 0x2
SCM_CREDENTIALS = 0x2
SCM_RIGHTS = 0x01
SF_CLOSE = 0x00000002
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_RDWR = 2
SHUT_WR = 1
SOCK_CLOEXEC = 0x00001000
SOCK_CONN_DGRAM = 6
SOCK_DGRAM = 2
SOCK_NONBLOCK = 0x800
SOCK_RAW = 3
SOCK_RDM = 4
SOCK_SEQPACKET = 5
@@ -378,8 +484,6 @@ const (
S_IFMST = 0x00FF0000
TCP_KEEPALIVE = 0x8
TCP_NODELAY = 0x1
TCP_INFO = 0xb
TCP_USER_TIMEOUT = 0x1
TIOCGWINSZ = 0x4008a368
TIOCSWINSZ = 0x8008a367
TIOCSBRK = 0x2000a77b
@@ -427,7 +531,10 @@ const (
VSUSP = 9
VTIME = 10
WCONTINUED = 0x4
WEXITED = 0x8
WNOHANG = 0x1
WNOWAIT = 0x20
WSTOPPED = 0x10
WUNTRACED = 0x2
_BPX_SWAP = 1
_BPX_NONSWAP = 2
@@ -452,8 +559,28 @@ const (
MADV_FREE = 15 // for Linux compatibility -- no zos semantics
MADV_WIPEONFORK = 16 // 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_FDCWD = 2 // for Unix compatibility -- no zos semantics
AT_SYMLINK_FOLLOW = 0x400
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 (
@@ -476,6 +603,7 @@ const (
EMLINK = Errno(125)
ENAMETOOLONG = Errno(126)
ENFILE = Errno(127)
ENOATTR = Errno(265)
ENODEV = Errno(128)
ENOENT = Errno(129)
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."},
{146, "EDC5146I", "Too many levels of symbolic links."},
{147, "EDC5147I", "Illegal byte sequence."},
{148, "", ""},
{148, "EDC5148I", "The named attribute or data not available."},
{149, "EDC5149I", "Value Overflow Error."},
{150, "EDC5150I", "UNIX System Services is not active."},
{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."},
{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."},
{265, "EDC5265I", "The named attribute not available."},
{1000, "EDC8000I", "A bad socket-call constant 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."},

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_WAIT = 455
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_WAIT = 455
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_WAIT = 455
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_WAIT = 455
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_WAIT = 455
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_WAIT = 4455
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_WAIT = 5455
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_WAIT = 5455
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_WAIT = 4455
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_WAIT = 455
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_WAIT = 455
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_WAIT = 455
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_WAIT = 455
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_WAIT = 455
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_WAIT = 455
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_HW_INDEX_SHIFT = 0x11
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_KERNEL = 0x2
PERF_SAMPLE_BRANCH_HV = 0x4
@@ -1198,7 +1199,7 @@ const (
PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000
PERF_SAMPLE_BRANCH_HW_INDEX = 0x20000
PERF_SAMPLE_BRANCH_PRIV_SAVE = 0x40000
PERF_SAMPLE_BRANCH_MAX = 0x80000
PERF_SAMPLE_BRANCH_MAX = 0x100000
PERF_BR_UNKNOWN = 0x0
PERF_BR_COND = 0x1
PERF_BR_UNCOND = 0x2
@@ -2481,6 +2482,15 @@ type XDPMmapOffsets struct {
Cr XDPRingOffset
}
type XDPUmemReg struct {
Addr uint64
Len uint64
Chunk_size uint32
Headroom uint32
Flags uint32
Tx_metadata_len uint32
}
type XDPStatistics struct {
Rx_dropped uint64
Rx_invalid_descs uint64
@@ -2935,7 +2945,7 @@ const (
BPF_TCP_LISTEN = 0xa
BPF_TCP_CLOSING = 0xb
BPF_TCP_NEW_SYN_RECV = 0xc
BPF_TCP_MAX_STATES = 0xd
BPF_TCP_MAX_STATES = 0xe
TCP_BPF_IW = 0x3e9
TCP_BPF_SNDCWND_CLAMP = 0x3ea
TCP_BPF_DELACK_MAX = 0x3eb
@@ -3211,7 +3221,7 @@ const (
DEVLINK_CMD_LINECARD_NEW = 0x50
DEVLINK_CMD_LINECARD_DEL = 0x51
DEVLINK_CMD_SELFTESTS_GET = 0x52
DEVLINK_CMD_MAX = 0x53
DEVLINK_CMD_MAX = 0x54
DEVLINK_PORT_TYPE_NOTSET = 0x0
DEVLINK_PORT_TYPE_AUTO = 0x1
DEVLINK_PORT_TYPE_ETH = 0x2
@@ -4595,7 +4605,7 @@ const (
NL80211_ATTR_MAC_HINT = 0xc8
NL80211_ATTR_MAC_MASK = 0xd7
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_CSA_COUNTERS = 0xce
NL80211_ATTR_MAX_MATCH_SETS = 0x85
@@ -4861,7 +4871,7 @@ const (
NL80211_BSS_FREQUENCY_OFFSET = 0x14
NL80211_BSS_INFORMATION_ELEMENTS = 0x6
NL80211_BSS_LAST_SEEN_BOOTTIME = 0xf
NL80211_BSS_MAX = 0x16
NL80211_BSS_MAX = 0x18
NL80211_BSS_MLD_ADDR = 0x16
NL80211_BSS_MLO_LINK_ID = 0x15
NL80211_BSS_PAD = 0x10
@@ -4965,7 +4975,7 @@ const (
NL80211_CMD_LEAVE_IBSS = 0x2c
NL80211_CMD_LEAVE_MESH = 0x45
NL80211_CMD_LEAVE_OCB = 0x6d
NL80211_CMD_MAX = 0x9a
NL80211_CMD_MAX = 0x9b
NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29
NL80211_CMD_MODIFY_LINK_STA = 0x97
NL80211_CMD_NAN_MATCH = 0x78
@@ -5199,7 +5209,7 @@ const (
NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf
NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe
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_NO_10MHZ = 0x11
NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc

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