Update vendored runc to v1.0.0.0-rc94
Note that this is the code in containerd that uses runc (as almost a library). Please see the other commit for the update to runc binary itself. Signed-off-by: Davanum Srinivas <davanum@gmail.com>
This commit is contained in:
parent
5c99f150ae
commit
de6db4038c
@ -6,9 +6,9 @@
|
||||
# 3.) $ make binaries install test
|
||||
#
|
||||
# Use the RUNC_VERSION build-arg to build with a custom version of runc, for example,
|
||||
# to build runc v1.0.0-rc93, use:
|
||||
# to build runc v1.0.0-rc94, use:
|
||||
#
|
||||
# docker build -t containerd-test --build-arg RUNC_VERSION=v1.0.0-rc93 -f Dockerfile.test ../
|
||||
# docker build -t containerd-test --build-arg RUNC_VERSION=v1.0.0-rc94 -f Dockerfile.test ../
|
||||
|
||||
ARG GOLANG_VERSION=1.16.4
|
||||
|
||||
|
6
go.mod
6
go.mod
@ -19,7 +19,7 @@ require (
|
||||
github.com/containerd/typeurl v1.0.2
|
||||
github.com/containerd/zfs v1.0.0
|
||||
github.com/containernetworking/plugins v0.9.1
|
||||
github.com/coreos/go-systemd/v22 v22.1.0
|
||||
github.com/coreos/go-systemd/v22 v22.3.1
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c
|
||||
github.com/docker/go-metrics v0.0.1
|
||||
@ -40,8 +40,8 @@ require (
|
||||
github.com/moby/sys/symlink v0.1.0
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/opencontainers/runc v1.0.0-rc93
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d
|
||||
github.com/opencontainers/runc v1.0.0-rc94
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
|
||||
github.com/opencontainers/selinux v1.8.0
|
||||
github.com/pelletier/go-toml v1.8.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
|
21
go.sum
21
go.sum
@ -64,13 +64,14 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
|
||||
github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
||||
github.com/cilium/ebpf v0.4.0 h1:QlHdikaxALkqWasW8hAC1mfR0jdmvbfaBdBPFmRSglA=
|
||||
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||
github.com/cilium/ebpf v0.5.0 h1:E1KshmrMEtkMP2UjlWzfmUV1owWY+BnbL5FxxuatnrU=
|
||||
github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/containerd/aufs v1.0.0 h1:2oeJiwX5HstO7shSrPZjrohJZLzK36wvpdmzDRkL/LY=
|
||||
github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||
@ -119,8 +120,9 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd/v22 v22.1.0 h1:kq/SbG2BCKLkDKkjQf5OWwKWUKj1lgs3lFI4PxnR5lg=
|
||||
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/coreos/go-systemd/v22 v22.3.1 h1:7OO2CXWMYNDdaAzP51t4lCCZWwpQHmvPbm9sxWjm3So=
|
||||
github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
@ -185,8 +187,9 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c h1:RBUpb2b14UnmRHNd2uHz20ZHLDK+SW5Us/vWF5IHRaY=
|
||||
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/googleapis v1.3.2 h1:kX1es4djPJrsDhY7aZKJy7aZasdcB5oSOEphMjSB53c=
|
||||
github.com/gogo/googleapis v1.3.2/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
@ -306,7 +309,6 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM=
|
||||
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/symlink v0.1.0 h1:MTFZ74KtNI6qQQpuBxU+uKCim4WtOMokr03hCfJcazE=
|
||||
@ -342,11 +344,12 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v1.0.0-rc93 h1:x2UMpOOVf3kQ8arv/EsDGwim8PTNqzL1/EYDr/+scOM=
|
||||
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
|
||||
github.com/opencontainers/runc v1.0.0-rc94 h1:atqAFoBGp+Wkh9HKpYN3g/8NCbMzYG6SJrr+YgwamgM=
|
||||
github.com/opencontainers/runc v1.0.0-rc94/go.mod h1:z+bZxa/+Tz/FmYVWkhUajJdzFeOqjc5vrqskhVyHGUM=
|
||||
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d h1:pNa8metDkwZjb9g4T8s+krQ+HRgZAkqnXml+wNir/+s=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM=
|
||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
@ -593,7 +596,6 @@ golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs=
|
||||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -670,6 +672,7 @@ google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63 h1:YzfoEYWbODU5Fbt
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
|
29
vendor/github.com/cilium/ebpf/.golangci.yaml
generated
vendored
Normal file
29
vendor/github.com/cilium/ebpf/.golangci.yaml
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
---
|
||||
issues:
|
||||
exclude-rules:
|
||||
# syscall param structs will have unused fields in Go code.
|
||||
- path: syscall.*.go
|
||||
linters:
|
||||
- structcheck
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- deadcode
|
||||
- errcheck
|
||||
- goimports
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- misspell
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- typecheck
|
||||
- unused
|
||||
- varcheck
|
||||
|
||||
# Could be enabled later:
|
||||
# - gocyclo
|
||||
# - prealloc
|
||||
# - maligned
|
||||
# - gosec
|
10
vendor/github.com/cilium/ebpf/README.md
generated
vendored
10
vendor/github.com/cilium/ebpf/README.md
generated
vendored
@ -13,7 +13,7 @@ be used in long running processes.
|
||||
* [perf](https://pkg.go.dev/github.com/cilium/ebpf/perf) allows reading from a
|
||||
`PERF_EVENT_ARRAY`
|
||||
* [cmd/bpf2go](https://pkg.go.dev/github.com/cilium/ebpf/cmd/bpf2go) allows
|
||||
embedding eBPF in Go
|
||||
compiling and embedding eBPF programs in Go code
|
||||
|
||||
The library is maintained by [Cloudflare](https://www.cloudflare.com) and
|
||||
[Cilium](https://www.cilium.io). Feel free to
|
||||
@ -25,6 +25,14 @@ The library is maintained by [Cloudflare](https://www.cloudflare.com) and
|
||||
The package is production ready, but **the API is explicitly unstable right
|
||||
now**. Expect to update your code if you want to follow along.
|
||||
|
||||
## Getting Started
|
||||
|
||||
A small collection of Go and eBPF programs that serve as examples for building
|
||||
your own tools can be found under [examples/](examples/).
|
||||
|
||||
Contributions are highly encouraged, as they highlight certain use cases of
|
||||
eBPF and the library, and help shape the future of the project.
|
||||
|
||||
## Requirements
|
||||
|
||||
* A version of Go that is [supported by
|
||||
|
2
vendor/github.com/cilium/ebpf/asm/func.go
generated
vendored
2
vendor/github.com/cilium/ebpf/asm/func.go
generated
vendored
@ -7,7 +7,7 @@ type BuiltinFunc int32
|
||||
|
||||
// eBPF built-in functions
|
||||
//
|
||||
// You can renegerate this list using the following gawk script:
|
||||
// You can regenerate this list using the following gawk script:
|
||||
//
|
||||
// /FN\(.+\),/ {
|
||||
// match($1, /\((.+)\)/, r)
|
||||
|
4
vendor/github.com/cilium/ebpf/asm/instruction.go
generated
vendored
4
vendor/github.com/cilium/ebpf/asm/instruction.go
generated
vendored
@ -337,7 +337,7 @@ func (insns Instructions) ReferenceOffsets() map[string][]int {
|
||||
// You can control indentation of symbols by
|
||||
// specifying a width. Setting a precision controls the indentation of
|
||||
// instructions.
|
||||
// The default character is a tab, which can be overriden by specifying
|
||||
// The default character is a tab, which can be overridden by specifying
|
||||
// the ' ' space flag.
|
||||
func (insns Instructions) Format(f fmt.State, c rune) {
|
||||
if c != 's' && c != 'v' {
|
||||
@ -382,8 +382,6 @@ func (insns Instructions) Format(f fmt.State, c rune) {
|
||||
}
|
||||
fmt.Fprintf(f, "%s%*d: %v\n", indent, offsetWidth, iter.Offset, iter.Ins)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Marshal encodes a BPF program into the kernel format.
|
||||
|
131
vendor/github.com/cilium/ebpf/elf_reader.go
generated
vendored
131
vendor/github.com/cilium/ebpf/elf_reader.go
generated
vendored
@ -272,11 +272,12 @@ func (ec *elfCode) loadPrograms() (map[string]*ProgramSpec, error) {
|
||||
return nil, fmt.Errorf("program %s: %w", funcSym.Name, err)
|
||||
}
|
||||
|
||||
progType, attachType, attachTo := getProgType(sec.Name)
|
||||
progType, attachType, progFlags, attachTo := getProgType(sec.Name)
|
||||
|
||||
spec := &ProgramSpec{
|
||||
Name: funcSym.Name,
|
||||
Type: progType,
|
||||
Flags: progFlags,
|
||||
AttachType: attachType,
|
||||
AttachTo: attachTo,
|
||||
License: ec.license,
|
||||
@ -533,28 +534,25 @@ func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error {
|
||||
return fmt.Errorf("missing BTF")
|
||||
}
|
||||
|
||||
if len(sec.symbols) == 0 {
|
||||
return fmt.Errorf("section %v: no symbols", sec.Name)
|
||||
}
|
||||
|
||||
_, err := io.Copy(internal.DiscardZeroes{}, bufio.NewReader(sec.Open()))
|
||||
if err != nil {
|
||||
return fmt.Errorf("section %v: initializing BTF map definitions: %w", sec.Name, internal.ErrNotSupported)
|
||||
}
|
||||
|
||||
for _, sym := range sec.symbols {
|
||||
name := sym.Name
|
||||
if maps[name] != nil {
|
||||
return fmt.Errorf("section %v: map %v already exists", sec.Name, sym)
|
||||
}
|
||||
var ds btf.Datasec
|
||||
if err := ec.btf.FindType(sec.Name, &ds); err != nil {
|
||||
return fmt.Errorf("cannot find section '%s' in BTF: %w", sec.Name, err)
|
||||
}
|
||||
|
||||
// A global Var is created by declaring a struct with a 'structure variable',
|
||||
// as is common in eBPF C to declare eBPF maps. For example,
|
||||
// `struct { ... } map_name ...;` emits a global variable `map_name`
|
||||
// with the type of said struct (which can be anonymous).
|
||||
var v btf.Var
|
||||
if err := ec.btf.FindType(name, &v); err != nil {
|
||||
return fmt.Errorf("cannot find global variable '%s' in BTF: %w", name, err)
|
||||
for _, vs := range ds.Vars {
|
||||
v, ok := vs.Type.(*btf.Var)
|
||||
if !ok {
|
||||
return fmt.Errorf("section %v: unexpected type %s", sec.Name, vs.Type)
|
||||
}
|
||||
name := string(v.Name)
|
||||
|
||||
if maps[name] != nil {
|
||||
return fmt.Errorf("section %v: map %s already exists", sec.Name, name)
|
||||
}
|
||||
|
||||
mapStruct, ok := v.Type.(*btf.Struct)
|
||||
@ -834,56 +832,61 @@ func (ec *elfCode) loadDataSections(maps map[string]*MapSpec) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getProgType(sectionName string) (ProgramType, AttachType, string) {
|
||||
func getProgType(sectionName string) (ProgramType, AttachType, uint32, string) {
|
||||
types := map[string]struct {
|
||||
progType ProgramType
|
||||
attachType AttachType
|
||||
progFlags uint32
|
||||
}{
|
||||
// From https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/lib/bpf/libbpf.c
|
||||
"socket": {SocketFilter, AttachNone},
|
||||
"seccomp": {SocketFilter, AttachNone},
|
||||
"kprobe/": {Kprobe, AttachNone},
|
||||
"uprobe/": {Kprobe, AttachNone},
|
||||
"kretprobe/": {Kprobe, AttachNone},
|
||||
"uretprobe/": {Kprobe, AttachNone},
|
||||
"tracepoint/": {TracePoint, AttachNone},
|
||||
"raw_tracepoint/": {RawTracepoint, AttachNone},
|
||||
"xdp": {XDP, AttachNone},
|
||||
"perf_event": {PerfEvent, AttachNone},
|
||||
"lwt_in": {LWTIn, AttachNone},
|
||||
"lwt_out": {LWTOut, AttachNone},
|
||||
"lwt_xmit": {LWTXmit, AttachNone},
|
||||
"lwt_seg6local": {LWTSeg6Local, AttachNone},
|
||||
"sockops": {SockOps, AttachCGroupSockOps},
|
||||
"sk_skb/stream_parser": {SkSKB, AttachSkSKBStreamParser},
|
||||
"sk_skb/stream_verdict": {SkSKB, AttachSkSKBStreamParser},
|
||||
"sk_msg": {SkMsg, AttachSkSKBStreamVerdict},
|
||||
"lirc_mode2": {LircMode2, AttachLircMode2},
|
||||
"flow_dissector": {FlowDissector, AttachFlowDissector},
|
||||
"iter/": {Tracing, AttachTraceIter},
|
||||
"sk_lookup/": {SkLookup, AttachSkLookup},
|
||||
"lsm/": {LSM, AttachLSMMac},
|
||||
"socket": {SocketFilter, AttachNone, 0},
|
||||
"seccomp": {SocketFilter, AttachNone, 0},
|
||||
"kprobe/": {Kprobe, AttachNone, 0},
|
||||
"uprobe/": {Kprobe, AttachNone, 0},
|
||||
"kretprobe/": {Kprobe, AttachNone, 0},
|
||||
"uretprobe/": {Kprobe, AttachNone, 0},
|
||||
"tracepoint/": {TracePoint, AttachNone, 0},
|
||||
"raw_tracepoint/": {RawTracepoint, AttachNone, 0},
|
||||
"xdp": {XDP, AttachNone, 0},
|
||||
"perf_event": {PerfEvent, AttachNone, 0},
|
||||
"lwt_in": {LWTIn, AttachNone, 0},
|
||||
"lwt_out": {LWTOut, AttachNone, 0},
|
||||
"lwt_xmit": {LWTXmit, AttachNone, 0},
|
||||
"lwt_seg6local": {LWTSeg6Local, AttachNone, 0},
|
||||
"sockops": {SockOps, AttachCGroupSockOps, 0},
|
||||
"sk_skb/stream_parser": {SkSKB, AttachSkSKBStreamParser, 0},
|
||||
"sk_skb/stream_verdict": {SkSKB, AttachSkSKBStreamParser, 0},
|
||||
"sk_msg": {SkMsg, AttachSkSKBStreamVerdict, 0},
|
||||
"lirc_mode2": {LircMode2, AttachLircMode2, 0},
|
||||
"flow_dissector": {FlowDissector, AttachFlowDissector, 0},
|
||||
"iter/": {Tracing, AttachTraceIter, 0},
|
||||
"fentry.s/": {Tracing, AttachTraceFEntry, unix.BPF_F_SLEEPABLE},
|
||||
"fmod_ret.s/": {Tracing, AttachModifyReturn, unix.BPF_F_SLEEPABLE},
|
||||
"fexit.s/": {Tracing, AttachTraceFExit, unix.BPF_F_SLEEPABLE},
|
||||
"sk_lookup/": {SkLookup, AttachSkLookup, 0},
|
||||
"lsm/": {LSM, AttachLSMMac, 0},
|
||||
"lsm.s/": {LSM, AttachLSMMac, unix.BPF_F_SLEEPABLE},
|
||||
|
||||
"cgroup_skb/ingress": {CGroupSKB, AttachCGroupInetIngress},
|
||||
"cgroup_skb/egress": {CGroupSKB, AttachCGroupInetEgress},
|
||||
"cgroup/dev": {CGroupDevice, AttachCGroupDevice},
|
||||
"cgroup/skb": {CGroupSKB, AttachNone},
|
||||
"cgroup/sock": {CGroupSock, AttachCGroupInetSockCreate},
|
||||
"cgroup/post_bind4": {CGroupSock, AttachCGroupInet4PostBind},
|
||||
"cgroup/post_bind6": {CGroupSock, AttachCGroupInet6PostBind},
|
||||
"cgroup/bind4": {CGroupSockAddr, AttachCGroupInet4Bind},
|
||||
"cgroup/bind6": {CGroupSockAddr, AttachCGroupInet6Bind},
|
||||
"cgroup/connect4": {CGroupSockAddr, AttachCGroupInet4Connect},
|
||||
"cgroup/connect6": {CGroupSockAddr, AttachCGroupInet6Connect},
|
||||
"cgroup/sendmsg4": {CGroupSockAddr, AttachCGroupUDP4Sendmsg},
|
||||
"cgroup/sendmsg6": {CGroupSockAddr, AttachCGroupUDP6Sendmsg},
|
||||
"cgroup/recvmsg4": {CGroupSockAddr, AttachCGroupUDP4Recvmsg},
|
||||
"cgroup/recvmsg6": {CGroupSockAddr, AttachCGroupUDP6Recvmsg},
|
||||
"cgroup/sysctl": {CGroupSysctl, AttachCGroupSysctl},
|
||||
"cgroup/getsockopt": {CGroupSockopt, AttachCGroupGetsockopt},
|
||||
"cgroup/setsockopt": {CGroupSockopt, AttachCGroupSetsockopt},
|
||||
"classifier": {SchedCLS, AttachNone},
|
||||
"action": {SchedACT, AttachNone},
|
||||
"cgroup_skb/ingress": {CGroupSKB, AttachCGroupInetIngress, 0},
|
||||
"cgroup_skb/egress": {CGroupSKB, AttachCGroupInetEgress, 0},
|
||||
"cgroup/dev": {CGroupDevice, AttachCGroupDevice, 0},
|
||||
"cgroup/skb": {CGroupSKB, AttachNone, 0},
|
||||
"cgroup/sock": {CGroupSock, AttachCGroupInetSockCreate, 0},
|
||||
"cgroup/post_bind4": {CGroupSock, AttachCGroupInet4PostBind, 0},
|
||||
"cgroup/post_bind6": {CGroupSock, AttachCGroupInet6PostBind, 0},
|
||||
"cgroup/bind4": {CGroupSockAddr, AttachCGroupInet4Bind, 0},
|
||||
"cgroup/bind6": {CGroupSockAddr, AttachCGroupInet6Bind, 0},
|
||||
"cgroup/connect4": {CGroupSockAddr, AttachCGroupInet4Connect, 0},
|
||||
"cgroup/connect6": {CGroupSockAddr, AttachCGroupInet6Connect, 0},
|
||||
"cgroup/sendmsg4": {CGroupSockAddr, AttachCGroupUDP4Sendmsg, 0},
|
||||
"cgroup/sendmsg6": {CGroupSockAddr, AttachCGroupUDP6Sendmsg, 0},
|
||||
"cgroup/recvmsg4": {CGroupSockAddr, AttachCGroupUDP4Recvmsg, 0},
|
||||
"cgroup/recvmsg6": {CGroupSockAddr, AttachCGroupUDP6Recvmsg, 0},
|
||||
"cgroup/sysctl": {CGroupSysctl, AttachCGroupSysctl, 0},
|
||||
"cgroup/getsockopt": {CGroupSockopt, AttachCGroupGetsockopt, 0},
|
||||
"cgroup/setsockopt": {CGroupSockopt, AttachCGroupSetsockopt, 0},
|
||||
"classifier": {SchedCLS, AttachNone, 0},
|
||||
"action": {SchedACT, AttachNone, 0},
|
||||
}
|
||||
|
||||
for prefix, t := range types {
|
||||
@ -892,13 +895,13 @@ func getProgType(sectionName string) (ProgramType, AttachType, string) {
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(prefix, "/") {
|
||||
return t.progType, t.attachType, ""
|
||||
return t.progType, t.attachType, t.progFlags, ""
|
||||
}
|
||||
|
||||
return t.progType, t.attachType, sectionName[len(prefix):]
|
||||
return t.progType, t.attachType, t.progFlags, sectionName[len(prefix):]
|
||||
}
|
||||
|
||||
return UnspecifiedProgram, AttachNone, ""
|
||||
return UnspecifiedProgram, AttachNone, 0, ""
|
||||
}
|
||||
|
||||
func (ec *elfCode) loadRelocations(sec *elf.Section, symbols []elf.Symbol) (map[uint64]elf.Symbol, error) {
|
||||
|
4
vendor/github.com/cilium/ebpf/internal/btf/btf_types.go
generated
vendored
4
vendor/github.com/cilium/ebpf/internal/btf/btf_types.go
generated
vendored
@ -31,12 +31,14 @@ const (
|
||||
kindDatasec
|
||||
)
|
||||
|
||||
// btfFuncLinkage describes BTF function linkage metadata.
|
||||
type btfFuncLinkage uint8
|
||||
|
||||
// Equivalent of enum btf_func_linkage.
|
||||
const (
|
||||
linkageStatic btfFuncLinkage = iota
|
||||
linkageGlobal
|
||||
linkageExtern
|
||||
// linkageExtern // Currently unused in libbpf.
|
||||
)
|
||||
|
||||
const (
|
||||
|
38
vendor/github.com/cilium/ebpf/internal/feature.go
generated
vendored
38
vendor/github.com/cilium/ebpf/internal/feature.go
generated
vendored
@ -98,41 +98,3 @@ func FeatureTest(name, version string, fn FeatureTestFn) func() error {
|
||||
return ft.result
|
||||
}
|
||||
}
|
||||
|
||||
// A Version in the form Major.Minor.Patch.
|
||||
type Version [3]uint16
|
||||
|
||||
// NewVersion creates a version from a string like "Major.Minor.Patch".
|
||||
//
|
||||
// Patch is optional.
|
||||
func NewVersion(ver string) (Version, error) {
|
||||
var major, minor, patch uint16
|
||||
n, _ := fmt.Sscanf(ver, "%d.%d.%d", &major, &minor, &patch)
|
||||
if n < 2 {
|
||||
return Version{}, fmt.Errorf("invalid version: %s", ver)
|
||||
}
|
||||
return Version{major, minor, patch}, nil
|
||||
}
|
||||
|
||||
func (v Version) String() string {
|
||||
if v[2] == 0 {
|
||||
return fmt.Sprintf("v%d.%d", v[0], v[1])
|
||||
}
|
||||
return fmt.Sprintf("v%d.%d.%d", v[0], v[1], v[2])
|
||||
}
|
||||
|
||||
// Less returns true if the version is less than another version.
|
||||
func (v Version) Less(other Version) bool {
|
||||
for i, a := range v {
|
||||
if a == other[i] {
|
||||
continue
|
||||
}
|
||||
return a < other[i]
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Unspecified returns true if the version is all zero.
|
||||
func (v Version) Unspecified() bool {
|
||||
return v[0] == 0 && v[1] == 0 && v[2] == 0
|
||||
}
|
||||
|
@ -1,36 +1,38 @@
|
||||
package ebpf
|
||||
package internal
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/cilium/ebpf/internal"
|
||||
"github.com/cilium/ebpf/internal/unix"
|
||||
)
|
||||
|
||||
func pin(currentPath, newPath string, fd *internal.FD) error {
|
||||
func Pin(currentPath, newPath string, fd *FD) error {
|
||||
if newPath == "" {
|
||||
return errors.New("given pinning path cannot be empty")
|
||||
}
|
||||
if currentPath == "" {
|
||||
return internal.BPFObjPin(newPath, fd)
|
||||
}
|
||||
if currentPath == newPath {
|
||||
return nil
|
||||
}
|
||||
if currentPath == "" {
|
||||
return BPFObjPin(newPath, fd)
|
||||
}
|
||||
var err error
|
||||
// Object is now moved to the new pinning path.
|
||||
if err = os.Rename(currentPath, newPath); err == nil {
|
||||
// Renameat2 is used instead of os.Rename to disallow the new path replacing
|
||||
// an existing path.
|
||||
if err = unix.Renameat2(unix.AT_FDCWD, currentPath, unix.AT_FDCWD, newPath, unix.RENAME_NOREPLACE); err == nil {
|
||||
// Object is now moved to the new pinning path.
|
||||
return nil
|
||||
}
|
||||
if !os.IsNotExist(err) {
|
||||
return fmt.Errorf("unable to move pinned object to new path %v: %w", newPath, err)
|
||||
}
|
||||
// Internal state not in sync with the file system so let's fix it.
|
||||
return internal.BPFObjPin(newPath, fd)
|
||||
return BPFObjPin(newPath, fd)
|
||||
}
|
||||
|
||||
func unpin(pinnedPath string) error {
|
||||
func Unpin(pinnedPath string) error {
|
||||
if pinnedPath == "" {
|
||||
return nil
|
||||
}
|
15
vendor/github.com/cilium/ebpf/internal/ptr.go
generated
vendored
15
vendor/github.com/cilium/ebpf/internal/ptr.go
generated
vendored
@ -1,6 +1,10 @@
|
||||
package internal
|
||||
|
||||
import "unsafe"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/cilium/ebpf/internal/unix"
|
||||
)
|
||||
|
||||
// NewPointer creates a 64-bit pointer from an unsafe Pointer.
|
||||
func NewPointer(ptr unsafe.Pointer) Pointer {
|
||||
@ -22,9 +26,10 @@ func NewStringPointer(str string) Pointer {
|
||||
return Pointer{}
|
||||
}
|
||||
|
||||
// The kernel expects strings to be zero terminated
|
||||
buf := make([]byte, len(str)+1)
|
||||
copy(buf, str)
|
||||
p, err := unix.BytePtrFromString(str)
|
||||
if err != nil {
|
||||
return Pointer{}
|
||||
}
|
||||
|
||||
return Pointer{ptr: unsafe.Pointer(&buf[0])}
|
||||
return Pointer{ptr: unsafe.Pointer(p)}
|
||||
}
|
||||
|
5
vendor/github.com/cilium/ebpf/internal/syscall.go
generated
vendored
5
vendor/github.com/cilium/ebpf/internal/syscall.go
generated
vendored
@ -140,9 +140,10 @@ func BPFObjPin(fileName string, fd *FD) error {
|
||||
}
|
||||
|
||||
// BPFObjGet wraps BPF_OBJ_GET.
|
||||
func BPFObjGet(fileName string) (*FD, error) {
|
||||
func BPFObjGet(fileName string, flags uint32) (*FD, error) {
|
||||
attr := bpfObjAttr{
|
||||
fileName: NewStringPointer(fileName),
|
||||
fileName: NewStringPointer(fileName),
|
||||
fileFlags: flags,
|
||||
}
|
||||
ptr, err := BPF(BPF_OBJ_GET, unsafe.Pointer(&attr), unsafe.Sizeof(attr))
|
||||
if err != nil {
|
||||
|
31
vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
generated
vendored
31
vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
generated
vendored
@ -26,8 +26,11 @@ const (
|
||||
EBADF = linux.EBADF
|
||||
BPF_F_NO_PREALLOC = linux.BPF_F_NO_PREALLOC
|
||||
BPF_F_NUMA_NODE = linux.BPF_F_NUMA_NODE
|
||||
BPF_F_RDONLY = linux.BPF_F_RDONLY
|
||||
BPF_F_WRONLY = linux.BPF_F_WRONLY
|
||||
BPF_F_RDONLY_PROG = linux.BPF_F_RDONLY_PROG
|
||||
BPF_F_WRONLY_PROG = linux.BPF_F_WRONLY_PROG
|
||||
BPF_F_SLEEPABLE = linux.BPF_F_SLEEPABLE
|
||||
BPF_OBJ_NAME_LEN = linux.BPF_OBJ_NAME_LEN
|
||||
BPF_TAG_SIZE = linux.BPF_TAG_SIZE
|
||||
SYS_BPF = linux.SYS_BPF
|
||||
@ -40,13 +43,21 @@ const (
|
||||
PROT_WRITE = linux.PROT_WRITE
|
||||
MAP_SHARED = linux.MAP_SHARED
|
||||
PERF_TYPE_SOFTWARE = linux.PERF_TYPE_SOFTWARE
|
||||
PERF_TYPE_TRACEPOINT = linux.PERF_TYPE_TRACEPOINT
|
||||
PERF_COUNT_SW_BPF_OUTPUT = linux.PERF_COUNT_SW_BPF_OUTPUT
|
||||
PERF_EVENT_IOC_DISABLE = linux.PERF_EVENT_IOC_DISABLE
|
||||
PERF_EVENT_IOC_ENABLE = linux.PERF_EVENT_IOC_ENABLE
|
||||
PERF_EVENT_IOC_SET_BPF = linux.PERF_EVENT_IOC_SET_BPF
|
||||
PerfBitWatermark = linux.PerfBitWatermark
|
||||
PERF_SAMPLE_RAW = linux.PERF_SAMPLE_RAW
|
||||
PERF_FLAG_FD_CLOEXEC = linux.PERF_FLAG_FD_CLOEXEC
|
||||
RLIM_INFINITY = linux.RLIM_INFINITY
|
||||
RLIMIT_MEMLOCK = linux.RLIMIT_MEMLOCK
|
||||
BPF_STATS_RUN_TIME = linux.BPF_STATS_RUN_TIME
|
||||
PERF_RECORD_LOST = linux.PERF_RECORD_LOST
|
||||
PERF_RECORD_SAMPLE = linux.PERF_RECORD_SAMPLE
|
||||
AT_FDCWD = linux.AT_FDCWD
|
||||
RENAME_NOREPLACE = linux.RENAME_NOREPLACE
|
||||
)
|
||||
|
||||
// Statfs_t is a wrapper
|
||||
@ -70,6 +81,11 @@ func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
||||
return linux.FcntlInt(fd, cmd, arg)
|
||||
}
|
||||
|
||||
// IoctlSetInt is a wrapper
|
||||
func IoctlSetInt(fd int, req uint, value int) error {
|
||||
return linux.IoctlSetInt(fd, req, value)
|
||||
}
|
||||
|
||||
// Statfs is a wrapper
|
||||
func Statfs(path string, buf *Statfs_t) (err error) {
|
||||
return linux.Statfs(path, buf)
|
||||
@ -157,6 +173,21 @@ func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) {
|
||||
return linux.Tgkill(tgid, tid, sig)
|
||||
}
|
||||
|
||||
// BytePtrFromString is a wrapper
|
||||
func BytePtrFromString(s string) (*byte, error) {
|
||||
return linux.BytePtrFromString(s)
|
||||
}
|
||||
|
||||
// ByteSliceToString is a wrapper
|
||||
func ByteSliceToString(s []byte) string {
|
||||
return linux.ByteSliceToString(s)
|
||||
}
|
||||
|
||||
// Renameat2 is a wrapper
|
||||
func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) error {
|
||||
return linux.Renameat2(olddirfd, oldpath, newdirfd, newpath, flags)
|
||||
}
|
||||
|
||||
func KernelRelease() (string, error) {
|
||||
var uname Utsname
|
||||
err := Uname(&uname)
|
||||
|
32
vendor/github.com/cilium/ebpf/internal/unix/types_other.go
generated
vendored
32
vendor/github.com/cilium/ebpf/internal/unix/types_other.go
generated
vendored
@ -26,8 +26,11 @@ const (
|
||||
|
||||
BPF_F_NO_PREALLOC = 0
|
||||
BPF_F_NUMA_NODE = 0
|
||||
BPF_F_RDONLY = 0
|
||||
BPF_F_WRONLY = 0
|
||||
BPF_F_RDONLY_PROG = 0
|
||||
BPF_F_WRONLY_PROG = 0
|
||||
BPF_F_SLEEPABLE = 0
|
||||
BPF_OBJ_NAME_LEN = 0x10
|
||||
BPF_TAG_SIZE = 0x8
|
||||
SYS_BPF = 321
|
||||
@ -41,13 +44,21 @@ const (
|
||||
PROT_WRITE = 0x2
|
||||
MAP_SHARED = 0x1
|
||||
PERF_TYPE_SOFTWARE = 0x1
|
||||
PERF_TYPE_TRACEPOINT = 0
|
||||
PERF_COUNT_SW_BPF_OUTPUT = 0xa
|
||||
PERF_EVENT_IOC_DISABLE = 0
|
||||
PERF_EVENT_IOC_ENABLE = 0
|
||||
PERF_EVENT_IOC_SET_BPF = 0
|
||||
PerfBitWatermark = 0x4000
|
||||
PERF_SAMPLE_RAW = 0x400
|
||||
PERF_FLAG_FD_CLOEXEC = 0x8
|
||||
RLIM_INFINITY = 0x7fffffffffffffff
|
||||
RLIMIT_MEMLOCK = 8
|
||||
BPF_STATS_RUN_TIME = 0
|
||||
PERF_RECORD_LOST = 2
|
||||
PERF_RECORD_SAMPLE = 9
|
||||
AT_FDCWD = -0x2
|
||||
RENAME_NOREPLACE = 0x1
|
||||
)
|
||||
|
||||
// Statfs_t is a wrapper
|
||||
@ -87,6 +98,11 @@ func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
||||
return -1, errNonLinux
|
||||
}
|
||||
|
||||
// IoctlSetInt is a wrapper
|
||||
func IoctlSetInt(fd int, req uint, value int) error {
|
||||
return errNonLinux
|
||||
}
|
||||
|
||||
// Statfs is a wrapper
|
||||
func Statfs(path string, buf *Statfs_t) error {
|
||||
return errNonLinux
|
||||
@ -201,6 +217,7 @@ func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int
|
||||
// Utsname is a wrapper
|
||||
type Utsname struct {
|
||||
Release [65]byte
|
||||
Version [65]byte
|
||||
}
|
||||
|
||||
// Uname is a wrapper
|
||||
@ -223,6 +240,21 @@ func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) {
|
||||
return errNonLinux
|
||||
}
|
||||
|
||||
// BytePtrFromString is a wrapper
|
||||
func BytePtrFromString(s string) (*byte, error) {
|
||||
return nil, errNonLinux
|
||||
}
|
||||
|
||||
// ByteSliceToString is a wrapper
|
||||
func ByteSliceToString(s []byte) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Renameat2 is a wrapper
|
||||
func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) error {
|
||||
return errNonLinux
|
||||
}
|
||||
|
||||
func KernelRelease() (string, error) {
|
||||
return "", errNonLinux
|
||||
}
|
||||
|
163
vendor/github.com/cilium/ebpf/internal/version.go
generated
vendored
Normal file
163
vendor/github.com/cilium/ebpf/internal/version.go
generated
vendored
Normal file
@ -0,0 +1,163 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
"sync"
|
||||
|
||||
"github.com/cilium/ebpf/internal/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
// Version constant used in ELF binaries indicating that the loader needs to
|
||||
// substitute the eBPF program's version with the value of the kernel's
|
||||
// KERNEL_VERSION compile-time macro. Used for compatibility with BCC, gobpf
|
||||
// and RedSift.
|
||||
MagicKernelVersion = 0xFFFFFFFE
|
||||
)
|
||||
|
||||
var (
|
||||
// Match between one and three decimals separated by dots, with the last
|
||||
// segment (patch level) being optional on some kernels.
|
||||
// The x.y.z string must appear at the start of a string or right after
|
||||
// whitespace to prevent sequences like 'x.y.z-a.b.c' from matching 'a.b.c'.
|
||||
rgxKernelVersion = regexp.MustCompile(`(?:\A|\s)\d{1,3}\.\d{1,3}(?:\.\d{1,3})?`)
|
||||
|
||||
kernelVersion = struct {
|
||||
once sync.Once
|
||||
version Version
|
||||
err error
|
||||
}{}
|
||||
)
|
||||
|
||||
// A Version in the form Major.Minor.Patch.
|
||||
type Version [3]uint16
|
||||
|
||||
// NewVersion creates a version from a string like "Major.Minor.Patch".
|
||||
//
|
||||
// Patch is optional.
|
||||
func NewVersion(ver string) (Version, error) {
|
||||
var major, minor, patch uint16
|
||||
n, _ := fmt.Sscanf(ver, "%d.%d.%d", &major, &minor, &patch)
|
||||
if n < 2 {
|
||||
return Version{}, fmt.Errorf("invalid version: %s", ver)
|
||||
}
|
||||
return Version{major, minor, patch}, nil
|
||||
}
|
||||
|
||||
func (v Version) String() string {
|
||||
if v[2] == 0 {
|
||||
return fmt.Sprintf("v%d.%d", v[0], v[1])
|
||||
}
|
||||
return fmt.Sprintf("v%d.%d.%d", v[0], v[1], v[2])
|
||||
}
|
||||
|
||||
// Less returns true if the version is less than another version.
|
||||
func (v Version) Less(other Version) bool {
|
||||
for i, a := range v {
|
||||
if a == other[i] {
|
||||
continue
|
||||
}
|
||||
return a < other[i]
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Unspecified returns true if the version is all zero.
|
||||
func (v Version) Unspecified() bool {
|
||||
return v[0] == 0 && v[1] == 0 && v[2] == 0
|
||||
}
|
||||
|
||||
// Kernel implements the kernel's KERNEL_VERSION macro from linux/version.h.
|
||||
// It represents the kernel version and patch level as a single value.
|
||||
func (v Version) Kernel() uint32 {
|
||||
|
||||
// Kernels 4.4 and 4.9 have their SUBLEVEL clamped to 255 to avoid
|
||||
// overflowing into PATCHLEVEL.
|
||||
// See kernel commit 9b82f13e7ef3 ("kbuild: clamp SUBLEVEL to 255").
|
||||
s := v[2]
|
||||
if s > 255 {
|
||||
s = 255
|
||||
}
|
||||
|
||||
// Truncate members to uint8 to prevent them from spilling over into
|
||||
// each other when overflowing 8 bits.
|
||||
return uint32(uint8(v[0]))<<16 | uint32(uint8(v[1]))<<8 | uint32(uint8(s))
|
||||
}
|
||||
|
||||
// KernelVersion returns the version of the currently running kernel.
|
||||
func KernelVersion() (Version, error) {
|
||||
kernelVersion.once.Do(func() {
|
||||
kernelVersion.version, kernelVersion.err = detectKernelVersion()
|
||||
})
|
||||
|
||||
if kernelVersion.err != nil {
|
||||
return Version{}, kernelVersion.err
|
||||
}
|
||||
return kernelVersion.version, nil
|
||||
}
|
||||
|
||||
// detectKernelVersion returns the version of the running kernel. It scans the
|
||||
// following sources in order: /proc/version_signature, uname -v, uname -r.
|
||||
// In each of those locations, the last-appearing x.y(.z) value is selected
|
||||
// for parsing. The first location that yields a usable version number is
|
||||
// returned.
|
||||
func detectKernelVersion() (Version, error) {
|
||||
|
||||
// Try reading /proc/version_signature for Ubuntu compatibility.
|
||||
// Example format: Ubuntu 4.15.0-91.92-generic 4.15.18
|
||||
// This method exists in the kernel itself, see d18acd15c
|
||||
// ("perf tools: Fix kernel version error in ubuntu").
|
||||
if pvs, err := ioutil.ReadFile("/proc/version_signature"); err == nil {
|
||||
// If /proc/version_signature exists, failing to parse it is an error.
|
||||
// It only exists on Ubuntu, where the real patch level is not obtainable
|
||||
// through any other method.
|
||||
v, err := findKernelVersion(string(pvs))
|
||||
if err != nil {
|
||||
return Version{}, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
var uname unix.Utsname
|
||||
if err := unix.Uname(&uname); err != nil {
|
||||
return Version{}, fmt.Errorf("calling uname: %w", err)
|
||||
}
|
||||
|
||||
// Debian puts the version including the patch level in uname.Version.
|
||||
// It is not an error if there's no version number in uname.Version,
|
||||
// as most distributions don't use it. Parsing can continue on uname.Release.
|
||||
// Example format: #1 SMP Debian 4.19.37-5+deb10u2 (2019-08-08)
|
||||
if v, err := findKernelVersion(unix.ByteSliceToString(uname.Version[:])); err == nil {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Most other distributions have the full kernel version including patch
|
||||
// level in uname.Release.
|
||||
// Example format: 4.19.0-5-amd64, 5.5.10-arch1-1
|
||||
v, err := findKernelVersion(unix.ByteSliceToString(uname.Release[:]))
|
||||
if err != nil {
|
||||
return Version{}, err
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// findKernelVersion matches s against rgxKernelVersion and parses the result
|
||||
// into a Version. If s contains multiple matches, the last entry is selected.
|
||||
func findKernelVersion(s string) (Version, error) {
|
||||
m := rgxKernelVersion.FindAllString(s, -1)
|
||||
if m == nil {
|
||||
return Version{}, fmt.Errorf("no kernel version in string: %s", s)
|
||||
}
|
||||
// Pick the last match of the string in case there are multiple.
|
||||
s = m[len(m)-1]
|
||||
|
||||
v, err := NewVersion(s)
|
||||
if err != nil {
|
||||
return Version{}, fmt.Errorf("parsing version string %s: %w", s, err)
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
16
vendor/github.com/cilium/ebpf/link/cgroup.go
generated
vendored
16
vendor/github.com/cilium/ebpf/link/cgroup.go
generated
vendored
@ -57,13 +57,13 @@ func AttachCgroup(opts CgroupOptions) (Link, error) {
|
||||
}
|
||||
|
||||
// LoadPinnedCgroup loads a pinned cgroup from a bpffs.
|
||||
func LoadPinnedCgroup(fileName string) (Link, error) {
|
||||
link, err := LoadPinnedRawLink(fileName)
|
||||
func LoadPinnedCgroup(fileName string, opts *ebpf.LoadPinOptions) (Link, error) {
|
||||
link, err := LoadPinnedRawLink(fileName, CgroupType, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &linkCgroup{link}, nil
|
||||
return &linkCgroup{*link}, nil
|
||||
}
|
||||
|
||||
type progAttachCgroup struct {
|
||||
@ -147,14 +147,16 @@ func (cg *progAttachCgroup) Pin(string) error {
|
||||
return fmt.Errorf("can't pin cgroup: %w", ErrNotSupported)
|
||||
}
|
||||
|
||||
func (cg *progAttachCgroup) Unpin() error {
|
||||
return fmt.Errorf("can't pin cgroup: %w", ErrNotSupported)
|
||||
}
|
||||
|
||||
type linkCgroup struct {
|
||||
*RawLink
|
||||
RawLink
|
||||
}
|
||||
|
||||
var _ Link = (*linkCgroup)(nil)
|
||||
|
||||
func (cg *linkCgroup) isLink() {}
|
||||
|
||||
func newLinkCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Program) (*linkCgroup, error) {
|
||||
link, err := AttachRawLink(RawLinkOptions{
|
||||
Target: int(cgroup.Fd()),
|
||||
@ -165,5 +167,5 @@ func newLinkCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Program)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &linkCgroup{link}, err
|
||||
return &linkCgroup{*link}, err
|
||||
}
|
||||
|
36
vendor/github.com/cilium/ebpf/link/iter.go
generated
vendored
36
vendor/github.com/cilium/ebpf/link/iter.go
generated
vendored
@ -27,53 +27,29 @@ func AttachIter(opts IterOptions) (*Iter, error) {
|
||||
return nil, fmt.Errorf("can't link iterator: %w", err)
|
||||
}
|
||||
|
||||
return &Iter{link}, err
|
||||
return &Iter{*link}, err
|
||||
}
|
||||
|
||||
// LoadPinnedIter loads a pinned iterator from a bpffs.
|
||||
func LoadPinnedIter(fileName string) (*Iter, error) {
|
||||
link, err := LoadPinnedRawLink(fileName)
|
||||
func LoadPinnedIter(fileName string, opts *ebpf.LoadPinOptions) (*Iter, error) {
|
||||
link, err := LoadPinnedRawLink(fileName, IterType, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Iter{link}, err
|
||||
return &Iter{*link}, err
|
||||
}
|
||||
|
||||
// Iter represents an attached bpf_iter.
|
||||
type Iter struct {
|
||||
link *RawLink
|
||||
}
|
||||
|
||||
var _ Link = (*Iter)(nil)
|
||||
|
||||
func (it *Iter) isLink() {}
|
||||
|
||||
// FD returns the underlying file descriptor.
|
||||
func (it *Iter) FD() int {
|
||||
return it.link.FD()
|
||||
}
|
||||
|
||||
// Close implements Link.
|
||||
func (it *Iter) Close() error {
|
||||
return it.link.Close()
|
||||
}
|
||||
|
||||
// Pin implements Link.
|
||||
func (it *Iter) Pin(fileName string) error {
|
||||
return it.link.Pin(fileName)
|
||||
}
|
||||
|
||||
// Update implements Link.
|
||||
func (it *Iter) Update(new *ebpf.Program) error {
|
||||
return it.link.Update(new)
|
||||
RawLink
|
||||
}
|
||||
|
||||
// Open creates a new instance of the iterator.
|
||||
//
|
||||
// Reading from the returned reader triggers the BPF program.
|
||||
func (it *Iter) Open() (io.ReadCloser, error) {
|
||||
linkFd, err := it.link.fd.Value()
|
||||
linkFd, err := it.fd.Value()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
296
vendor/github.com/cilium/ebpf/link/kprobe.go
generated
vendored
Normal file
296
vendor/github.com/cilium/ebpf/link/kprobe.go
generated
vendored
Normal file
@ -0,0 +1,296 @@
|
||||
package link
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/cilium/ebpf"
|
||||
"github.com/cilium/ebpf/internal"
|
||||
"github.com/cilium/ebpf/internal/unix"
|
||||
)
|
||||
|
||||
var (
|
||||
kprobeEventsPath = filepath.Join(tracefsPath, "kprobe_events")
|
||||
)
|
||||
|
||||
// Kprobe attaches the given eBPF program to a perf event that fires when the
|
||||
// given kernel symbol starts executing. See /proc/kallsyms for available
|
||||
// symbols. For example, printk():
|
||||
//
|
||||
// Kprobe("printk")
|
||||
//
|
||||
// The resulting Link must be Closed during program shutdown to avoid leaking
|
||||
// system resources.
|
||||
func Kprobe(symbol string, prog *ebpf.Program) (Link, error) {
|
||||
k, err := kprobe(symbol, prog, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = k.attach(prog)
|
||||
if err != nil {
|
||||
k.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// Kretprobe attaches the given eBPF program to a perf event that fires right
|
||||
// before the given kernel symbol exits, with the function stack left intact.
|
||||
// See /proc/kallsyms for available symbols. For example, printk():
|
||||
//
|
||||
// Kretprobe("printk")
|
||||
//
|
||||
// The resulting Link must be Closed during program shutdown to avoid leaking
|
||||
// system resources.
|
||||
func Kretprobe(symbol string, prog *ebpf.Program) (Link, error) {
|
||||
k, err := kprobe(symbol, prog, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = k.attach(prog)
|
||||
if err != nil {
|
||||
k.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// kprobe opens a perf event on the given symbol and attaches prog to it.
|
||||
// If ret is true, create a kretprobe.
|
||||
func kprobe(symbol string, prog *ebpf.Program, ret bool) (*perfEvent, error) {
|
||||
if symbol == "" {
|
||||
return nil, fmt.Errorf("symbol name cannot be empty: %w", errInvalidInput)
|
||||
}
|
||||
if prog == nil {
|
||||
return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput)
|
||||
}
|
||||
if !rgxTraceEvent.MatchString(symbol) {
|
||||
return nil, fmt.Errorf("symbol '%s' must be alphanumeric or underscore: %w", symbol, errInvalidInput)
|
||||
}
|
||||
if prog.Type() != ebpf.Kprobe {
|
||||
return nil, fmt.Errorf("eBPF program type %s is not a Kprobe: %w", prog.Type(), errInvalidInput)
|
||||
}
|
||||
|
||||
// Use kprobe PMU if the kernel has it available.
|
||||
tp, err := pmuKprobe(symbol, ret)
|
||||
if err == nil {
|
||||
return tp, nil
|
||||
}
|
||||
if err != nil && !errors.Is(err, ErrNotSupported) {
|
||||
return nil, fmt.Errorf("creating perf_kprobe PMU: %w", err)
|
||||
}
|
||||
|
||||
// Use tracefs if kprobe PMU is missing.
|
||||
tp, err = tracefsKprobe(symbol, ret)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating trace event '%s' in tracefs: %w", symbol, err)
|
||||
}
|
||||
|
||||
return tp, nil
|
||||
}
|
||||
|
||||
// pmuKprobe opens a perf event based on a Performance Monitoring Unit.
|
||||
// Requires at least 4.17 (e12f03d7031a "perf/core: Implement the
|
||||
// 'perf_kprobe' PMU").
|
||||
// Returns ErrNotSupported if the kernel doesn't support perf_kprobe PMU,
|
||||
// or os.ErrNotExist if the given symbol does not exist in the kernel.
|
||||
func pmuKprobe(symbol string, ret bool) (*perfEvent, error) {
|
||||
|
||||
// Getting the PMU type will fail if the kernel doesn't support
|
||||
// the perf_kprobe PMU.
|
||||
et, err := getPMUEventType("kprobe")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create a pointer to a NUL-terminated string for the kernel.
|
||||
sp, err := unsafeStringPtr(symbol)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: Parse the position of the bit from /sys/bus/event_source/devices/%s/format/retprobe.
|
||||
config := 0
|
||||
if ret {
|
||||
config = 1
|
||||
}
|
||||
|
||||
attr := unix.PerfEventAttr{
|
||||
Type: uint32(et), // PMU event type read from sysfs
|
||||
Ext1: uint64(uintptr(sp)), // Kernel symbol to trace
|
||||
Config: uint64(config), // perf_kprobe PMU treats config as flags
|
||||
}
|
||||
|
||||
fd, err := unix.PerfEventOpen(&attr, perfAllThreads, 0, -1, unix.PERF_FLAG_FD_CLOEXEC)
|
||||
|
||||
// Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL
|
||||
// when trying to create a kretprobe for a missing symbol. Make sure ENOENT
|
||||
// is returned to the caller.
|
||||
if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) {
|
||||
return nil, fmt.Errorf("symbol '%s' not found: %w", symbol, os.ErrNotExist)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("opening perf event: %w", err)
|
||||
}
|
||||
|
||||
// Ensure the string pointer is not collected before PerfEventOpen returns.
|
||||
runtime.KeepAlive(sp)
|
||||
|
||||
// Kernel has perf_kprobe PMU available, initialize perf event.
|
||||
return &perfEvent{
|
||||
fd: internal.NewFD(uint32(fd)),
|
||||
pmuID: et,
|
||||
name: symbol,
|
||||
ret: ret,
|
||||
progType: ebpf.Kprobe,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// tracefsKprobe creates a trace event by writing an entry to <tracefs>/kprobe_events.
|
||||
// A new trace event group name is generated on every call to support creating
|
||||
// multiple trace events for the same kernel symbol. A perf event is then opened
|
||||
// on the newly-created trace event and returned to the caller.
|
||||
func tracefsKprobe(symbol string, ret bool) (*perfEvent, error) {
|
||||
|
||||
// Generate a random string for each trace event we attempt to create.
|
||||
// This value is used as the 'group' token in tracefs to allow creating
|
||||
// multiple kprobe trace events with the same name.
|
||||
group, err := randomGroup("ebpf")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("randomizing group name: %w", err)
|
||||
}
|
||||
|
||||
// Before attempting to create a trace event through tracefs,
|
||||
// check if an event with the same group and name already exists.
|
||||
// Kernels 4.x and earlier don't return os.ErrExist on writing a duplicate
|
||||
// entry, so we need to rely on reads for detecting uniqueness.
|
||||
_, err = getTraceEventID(group, symbol)
|
||||
if err == nil {
|
||||
return nil, fmt.Errorf("trace event already exists: %s/%s", group, symbol)
|
||||
}
|
||||
// The read is expected to fail with ErrNotSupported due to a non-existing event.
|
||||
if err != nil && !errors.Is(err, ErrNotSupported) {
|
||||
return nil, fmt.Errorf("checking trace event %s/%s: %w", group, symbol, err)
|
||||
}
|
||||
|
||||
// Create the kprobe trace event using tracefs.
|
||||
if err := createTraceFSKprobeEvent(group, symbol, ret); err != nil {
|
||||
return nil, fmt.Errorf("creating kprobe event on tracefs: %w", err)
|
||||
}
|
||||
|
||||
// Get the newly-created trace event's id.
|
||||
tid, err := getTraceEventID(group, symbol)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting trace event id: %w", err)
|
||||
}
|
||||
|
||||
// Kprobes are ephemeral tracepoints and share the same perf event type.
|
||||
fd, err := openTracepointPerfEvent(tid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &perfEvent{
|
||||
fd: fd,
|
||||
group: group,
|
||||
name: symbol,
|
||||
ret: ret,
|
||||
tracefsID: tid,
|
||||
progType: ebpf.Kprobe, // kernel only allows attaching kprobe programs to kprobe events
|
||||
}, nil
|
||||
}
|
||||
|
||||
// createTraceFSKprobeEvent creates a new ephemeral trace event by writing to
|
||||
// <tracefs>/kprobe_events. Returns ErrNotSupported if symbol is not a valid
|
||||
// kernel symbol, or if it is not traceable with kprobes.
|
||||
func createTraceFSKprobeEvent(group, symbol string, ret bool) error {
|
||||
// Open the kprobe_events file in tracefs.
|
||||
f, err := os.OpenFile(kprobeEventsPath, os.O_APPEND|os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error opening kprobe_events: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// The kprobe_events syntax is as follows (see Documentation/trace/kprobetrace.txt):
|
||||
// p[:[GRP/]EVENT] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS] : Set a probe
|
||||
// r[MAXACTIVE][:[GRP/]EVENT] [MOD:]SYM[+0] [FETCHARGS] : Set a return probe
|
||||
// -:[GRP/]EVENT : Clear a probe
|
||||
//
|
||||
// Some examples:
|
||||
// r:ebpf_1234/r_my_kretprobe nf_conntrack_destroy
|
||||
// p:ebpf_5678/p_my_kprobe __x64_sys_execve
|
||||
//
|
||||
// Leaving the kretprobe's MAXACTIVE set to 0 (or absent) will make the
|
||||
// kernel default to NR_CPUS. This is desired in most eBPF cases since
|
||||
// subsampling or rate limiting logic can be more accurately implemented in
|
||||
// the eBPF program itself. See Documentation/kprobes.txt for more details.
|
||||
pe := fmt.Sprintf("%s:%s/%s %s", kprobePrefix(ret), group, symbol, symbol)
|
||||
_, err = f.WriteString(pe)
|
||||
// Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL
|
||||
// when trying to create a kretprobe for a missing symbol. Make sure ENOENT
|
||||
// is returned to the caller.
|
||||
if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) {
|
||||
return fmt.Errorf("kernel symbol %s not found: %w", symbol, os.ErrNotExist)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("writing '%s' to kprobe_events: %w", pe, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// closeTraceFSKprobeEvent removes the kprobe with the given group, symbol and kind
|
||||
// from <tracefs>/kprobe_events.
|
||||
func closeTraceFSKprobeEvent(group, symbol string) error {
|
||||
f, err := os.OpenFile(kprobeEventsPath, os.O_APPEND|os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error opening kprobe_events: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// See kprobe_events syntax above. Kprobe type does not need to be specified
|
||||
// for removals.
|
||||
pe := fmt.Sprintf("-:%s/%s", group, symbol)
|
||||
if _, err = f.WriteString(pe); err != nil {
|
||||
return fmt.Errorf("writing '%s' to kprobe_events: %w", pe, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// randomGroup generates a pseudorandom string for use as a tracefs group name.
|
||||
// Returns an error when the output string would exceed 63 characters (kernel
|
||||
// limitation), when rand.Read() fails or when prefix contains characters not
|
||||
// allowed by rgxTraceEvent.
|
||||
func randomGroup(prefix string) (string, error) {
|
||||
if !rgxTraceEvent.MatchString(prefix) {
|
||||
return "", fmt.Errorf("prefix '%s' must be alphanumeric or underscore: %w", prefix, errInvalidInput)
|
||||
}
|
||||
|
||||
b := make([]byte, 8)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
return "", fmt.Errorf("reading random bytes: %w", err)
|
||||
}
|
||||
|
||||
group := fmt.Sprintf("%s_%x", prefix, b)
|
||||
if len(group) > 63 {
|
||||
return "", fmt.Errorf("group name '%s' cannot be longer than 63 characters: %w", group, errInvalidInput)
|
||||
}
|
||||
|
||||
return group, nil
|
||||
}
|
||||
|
||||
func kprobePrefix(ret bool) string {
|
||||
if ret {
|
||||
return "r"
|
||||
}
|
||||
return "p"
|
||||
}
|
47
vendor/github.com/cilium/ebpf/link/link.go
generated
vendored
47
vendor/github.com/cilium/ebpf/link/link.go
generated
vendored
@ -22,6 +22,11 @@ type Link interface {
|
||||
// May return an error wrapping ErrNotSupported.
|
||||
Pin(string) error
|
||||
|
||||
// Undo a previous call to Pin.
|
||||
//
|
||||
// May return an error wrapping ErrNotSupported.
|
||||
Unpin() error
|
||||
|
||||
// Close frees resources.
|
||||
//
|
||||
// The link will be broken unless it has been pinned. A link
|
||||
@ -58,7 +63,8 @@ type RawLinkInfo struct {
|
||||
// You should consider using the higher level interfaces in this
|
||||
// package instead.
|
||||
type RawLink struct {
|
||||
fd *internal.FD
|
||||
fd *internal.FD
|
||||
pinnedPath string
|
||||
}
|
||||
|
||||
// AttachRawLink creates a raw link.
|
||||
@ -86,22 +92,21 @@ func AttachRawLink(opts RawLinkOptions) (*RawLink, error) {
|
||||
return nil, fmt.Errorf("can't create link: %s", err)
|
||||
}
|
||||
|
||||
return &RawLink{fd}, nil
|
||||
return &RawLink{fd, ""}, nil
|
||||
}
|
||||
|
||||
// LoadPinnedRawLink loads a persisted link from a bpffs.
|
||||
func LoadPinnedRawLink(fileName string) (*RawLink, error) {
|
||||
return loadPinnedRawLink(fileName, UnspecifiedType)
|
||||
}
|
||||
|
||||
func loadPinnedRawLink(fileName string, typ Type) (*RawLink, error) {
|
||||
fd, err := internal.BPFObjGet(fileName)
|
||||
//
|
||||
// Returns an error if the pinned link type doesn't match linkType. Pass
|
||||
// UnspecifiedType to disable this behaviour.
|
||||
func LoadPinnedRawLink(fileName string, linkType Type, opts *ebpf.LoadPinOptions) (*RawLink, error) {
|
||||
fd, err := internal.BPFObjGet(fileName, opts.Marshal())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load pinned link: %s", err)
|
||||
return nil, fmt.Errorf("load pinned link: %w", err)
|
||||
}
|
||||
|
||||
link := &RawLink{fd}
|
||||
if typ == UnspecifiedType {
|
||||
link := &RawLink{fd, fileName}
|
||||
if linkType == UnspecifiedType {
|
||||
return link, nil
|
||||
}
|
||||
|
||||
@ -111,9 +116,9 @@ func loadPinnedRawLink(fileName string, typ Type) (*RawLink, error) {
|
||||
return nil, fmt.Errorf("get pinned link info: %s", err)
|
||||
}
|
||||
|
||||
if info.Type != typ {
|
||||
if info.Type != linkType {
|
||||
link.Close()
|
||||
return nil, fmt.Errorf("link type %v doesn't match %v", info.Type, typ)
|
||||
return nil, fmt.Errorf("link type %v doesn't match %v", info.Type, linkType)
|
||||
}
|
||||
|
||||
return link, nil
|
||||
@ -142,13 +147,23 @@ func (l *RawLink) Close() error {
|
||||
// Calling Close on a pinned Link will not break the link
|
||||
// until the pin is removed.
|
||||
func (l *RawLink) Pin(fileName string) error {
|
||||
if err := internal.BPFObjPin(fileName, l.fd); err != nil {
|
||||
return fmt.Errorf("can't pin link: %s", err)
|
||||
if err := internal.Pin(l.pinnedPath, fileName, l.fd); err != nil {
|
||||
return err
|
||||
}
|
||||
l.pinnedPath = fileName
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update implements Link.
|
||||
// Unpin implements the Link interface.
|
||||
func (l *RawLink) Unpin() error {
|
||||
if err := internal.Unpin(l.pinnedPath); err != nil {
|
||||
return err
|
||||
}
|
||||
l.pinnedPath = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update implements the Link interface.
|
||||
func (l *RawLink) Update(new *ebpf.Program) error {
|
||||
return l.UpdateArgs(RawLinkUpdateOptions{
|
||||
New: new,
|
||||
|
4
vendor/github.com/cilium/ebpf/link/netns.go
generated
vendored
4
vendor/github.com/cilium/ebpf/link/netns.go
generated
vendored
@ -41,8 +41,8 @@ func AttachNetNs(ns int, prog *ebpf.Program) (*NetNsLink, error) {
|
||||
}
|
||||
|
||||
// LoadPinnedNetNs loads a network namespace link from bpffs.
|
||||
func LoadPinnedNetNs(fileName string) (*NetNsLink, error) {
|
||||
link, err := loadPinnedRawLink(fileName, NetNsType)
|
||||
func LoadPinnedNetNs(fileName string, opts *ebpf.LoadPinOptions) (*NetNsLink, error) {
|
||||
link, err := LoadPinnedRawLink(fileName, NetNsType, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
253
vendor/github.com/cilium/ebpf/link/perf_event.go
generated
vendored
Normal file
253
vendor/github.com/cilium/ebpf/link/perf_event.go
generated
vendored
Normal file
@ -0,0 +1,253 @@
|
||||
package link
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/cilium/ebpf"
|
||||
"github.com/cilium/ebpf/internal"
|
||||
"github.com/cilium/ebpf/internal/unix"
|
||||
)
|
||||
|
||||
// Getting the terminology right is usually the hardest part. For posterity and
|
||||
// for staying sane during implementation:
|
||||
//
|
||||
// - trace event: Representation of a kernel runtime hook. Filesystem entries
|
||||
// under <tracefs>/events. Can be tracepoints (static), kprobes or uprobes.
|
||||
// Can be instantiated into perf events (see below).
|
||||
// - tracepoint: A predetermined hook point in the kernel. Exposed as trace
|
||||
// events in (sub)directories under <tracefs>/events. Cannot be closed or
|
||||
// removed, they are static.
|
||||
// - k(ret)probe: Ephemeral trace events based on entry or exit points of
|
||||
// exported kernel symbols. kprobe-based (tracefs) trace events can be
|
||||
// created system-wide by writing to the <tracefs>/kprobe_events file, or
|
||||
// they can be scoped to the current process by creating PMU perf events.
|
||||
// - perf event: An object instantiated based on an existing trace event or
|
||||
// kernel symbol. Referred to by fd in userspace.
|
||||
// Exactly one eBPF program can be attached to a perf event. Multiple perf
|
||||
// events can be created from a single trace event. Closing a perf event
|
||||
// stops any further invocations of the attached eBPF program.
|
||||
|
||||
var (
|
||||
tracefsPath = "/sys/kernel/debug/tracing"
|
||||
|
||||
// Trace event groups, names and kernel symbols must adhere to this set
|
||||
// of characters. Non-empty, first character must not be a number, all
|
||||
// characters must be alphanumeric or underscore.
|
||||
rgxTraceEvent = regexp.MustCompile("^[a-zA-Z_][0-9a-zA-Z_]*$")
|
||||
|
||||
errInvalidInput = errors.New("invalid input")
|
||||
)
|
||||
|
||||
const (
|
||||
perfAllThreads = -1
|
||||
)
|
||||
|
||||
// A perfEvent represents a perf event kernel object. Exactly one eBPF program
|
||||
// can be attached to it. It is created based on a tracefs trace event or a
|
||||
// Performance Monitoring Unit (PMU).
|
||||
type perfEvent struct {
|
||||
|
||||
// Group and name of the tracepoint/kprobe/uprobe.
|
||||
group string
|
||||
name string
|
||||
|
||||
// PMU event ID read from sysfs. Valid IDs are non-zero.
|
||||
pmuID uint64
|
||||
// ID of the trace event read from tracefs. Valid IDs are non-zero.
|
||||
tracefsID uint64
|
||||
|
||||
// True for kretprobes/uretprobes.
|
||||
ret bool
|
||||
|
||||
fd *internal.FD
|
||||
progType ebpf.ProgramType
|
||||
}
|
||||
|
||||
func (pe *perfEvent) isLink() {}
|
||||
|
||||
func (pe *perfEvent) Pin(string) error {
|
||||
return fmt.Errorf("pin perf event: %w", ErrNotSupported)
|
||||
}
|
||||
|
||||
func (pe *perfEvent) Unpin() error {
|
||||
return fmt.Errorf("unpin perf event: %w", ErrNotSupported)
|
||||
}
|
||||
|
||||
// Since 4.15 (e87c6bc3852b "bpf: permit multiple bpf attachments for a single perf event"),
|
||||
// calling PERF_EVENT_IOC_SET_BPF appends the given program to a prog_array
|
||||
// owned by the perf event, which means multiple programs can be attached
|
||||
// simultaneously.
|
||||
//
|
||||
// Before 4.15, calling PERF_EVENT_IOC_SET_BPF more than once on a perf event
|
||||
// returns EEXIST.
|
||||
//
|
||||
// Detaching a program from a perf event is currently not possible, so a
|
||||
// program replacement mechanism cannot be implemented for perf events.
|
||||
func (pe *perfEvent) Update(prog *ebpf.Program) error {
|
||||
return fmt.Errorf("can't replace eBPF program in perf event: %w", ErrNotSupported)
|
||||
}
|
||||
|
||||
func (pe *perfEvent) Close() error {
|
||||
if pe.fd == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
pfd, err := pe.fd.Value()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting perf event fd: %w", err)
|
||||
}
|
||||
|
||||
err = unix.IoctlSetInt(int(pfd), unix.PERF_EVENT_IOC_DISABLE, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("disabling perf event: %w", err)
|
||||
}
|
||||
|
||||
err = pe.fd.Close()
|
||||
if err != nil {
|
||||
return fmt.Errorf("closing perf event fd: %w", err)
|
||||
}
|
||||
|
||||
switch t := pe.progType; t {
|
||||
case ebpf.Kprobe:
|
||||
// For kprobes created using tracefs, clean up the <tracefs>/kprobe_events entry.
|
||||
if pe.tracefsID != 0 {
|
||||
return closeTraceFSKprobeEvent(pe.group, pe.name)
|
||||
}
|
||||
case ebpf.TracePoint:
|
||||
// Tracepoint trace events don't hold any extra resources.
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// attach the given eBPF prog to the perf event stored in pe.
|
||||
// pe must contain a valid perf event fd.
|
||||
// prog's type must match the program type stored in pe.
|
||||
func (pe *perfEvent) attach(prog *ebpf.Program) error {
|
||||
if prog == nil {
|
||||
return errors.New("cannot attach a nil program")
|
||||
}
|
||||
if pe.fd == nil {
|
||||
return errors.New("cannot attach to nil perf event")
|
||||
}
|
||||
if t := prog.Type(); t != pe.progType {
|
||||
return fmt.Errorf("invalid program type (expected %s): %s", pe.progType, t)
|
||||
}
|
||||
if prog.FD() < 0 {
|
||||
return fmt.Errorf("invalid program: %w", internal.ErrClosedFd)
|
||||
}
|
||||
|
||||
// The ioctl below will fail when the fd is invalid.
|
||||
kfd, _ := pe.fd.Value()
|
||||
|
||||
// Assign the eBPF program to the perf event.
|
||||
err := unix.IoctlSetInt(int(kfd), unix.PERF_EVENT_IOC_SET_BPF, prog.FD())
|
||||
if err != nil {
|
||||
return fmt.Errorf("setting perf event bpf program: %w", err)
|
||||
}
|
||||
|
||||
// PERF_EVENT_IOC_ENABLE and _DISABLE ignore their given values.
|
||||
if err := unix.IoctlSetInt(int(kfd), unix.PERF_EVENT_IOC_ENABLE, 0); err != nil {
|
||||
return fmt.Errorf("enable perf event: %s", err)
|
||||
}
|
||||
|
||||
// Close the perf event when its reference is lost to avoid leaking system resources.
|
||||
runtime.SetFinalizer(pe, (*perfEvent).Close)
|
||||
return nil
|
||||
}
|
||||
|
||||
// unsafeStringPtr returns an unsafe.Pointer to a NUL-terminated copy of str.
|
||||
func unsafeStringPtr(str string) (unsafe.Pointer, error) {
|
||||
p, err := unix.BytePtrFromString(str)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return unsafe.Pointer(p), nil
|
||||
}
|
||||
|
||||
// getTraceEventID reads a trace event's ID from tracefs given its group and name.
|
||||
// group and name must be alphanumeric or underscore, as required by the kernel.
|
||||
func getTraceEventID(group, name string) (uint64, error) {
|
||||
tid, err := uint64FromFile(tracefsPath, "events", group, name, "id")
|
||||
if errors.Is(err, ErrNotSupported) {
|
||||
return 0, fmt.Errorf("trace event %s/%s: %w", group, name, ErrNotSupported)
|
||||
}
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("reading trace event ID of %s/%s: %w", group, name, err)
|
||||
}
|
||||
|
||||
return tid, nil
|
||||
}
|
||||
|
||||
// getPMUEventType reads a Performance Monitoring Unit's type (numeric identifier)
|
||||
// from /sys/bus/event_source/devices/<pmu>/type.
|
||||
func getPMUEventType(pmu string) (uint64, error) {
|
||||
et, err := uint64FromFile("/sys/bus/event_source/devices", pmu, "type")
|
||||
if errors.Is(err, ErrNotSupported) {
|
||||
return 0, fmt.Errorf("pmu type %s: %w", pmu, ErrNotSupported)
|
||||
}
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("reading pmu type %s: %w", pmu, err)
|
||||
}
|
||||
|
||||
return et, nil
|
||||
}
|
||||
|
||||
// openTracepointPerfEvent opens a tracepoint-type perf event. System-wide
|
||||
// kprobes created by writing to <tracefs>/kprobe_events are tracepoints
|
||||
// behind the scenes, and can be attached to using these perf events.
|
||||
func openTracepointPerfEvent(tid uint64) (*internal.FD, error) {
|
||||
attr := unix.PerfEventAttr{
|
||||
Type: unix.PERF_TYPE_TRACEPOINT,
|
||||
Config: tid,
|
||||
Sample_type: unix.PERF_SAMPLE_RAW,
|
||||
Sample: 1,
|
||||
Wakeup: 1,
|
||||
}
|
||||
|
||||
fd, err := unix.PerfEventOpen(&attr, perfAllThreads, 0, -1, unix.PERF_FLAG_FD_CLOEXEC)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("opening tracepoint perf event: %w", err)
|
||||
}
|
||||
|
||||
return internal.NewFD(uint32(fd)), nil
|
||||
}
|
||||
|
||||
// uint64FromFile reads a uint64 from a file. All elements of path are sanitized
|
||||
// and joined onto base. Returns error if base no longer prefixes the path after
|
||||
// joining all components.
|
||||
func uint64FromFile(base string, path ...string) (uint64, error) {
|
||||
|
||||
// Resolve leaf path separately for error feedback. Makes the join onto
|
||||
// base more readable (can't mix with variadic args).
|
||||
l := filepath.Join(path...)
|
||||
|
||||
p := filepath.Join(base, l)
|
||||
if !strings.HasPrefix(p, base) {
|
||||
return 0, fmt.Errorf("path '%s' attempts to escape base path '%s': %w", l, base, errInvalidInput)
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(p)
|
||||
if os.IsNotExist(err) {
|
||||
// Only echo leaf path, the base path can be prepended at the call site
|
||||
// if more verbosity is required.
|
||||
return 0, fmt.Errorf("symbol %s: %w", l, ErrNotSupported)
|
||||
}
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("reading file %s: %w", p, err)
|
||||
}
|
||||
|
||||
et := bytes.TrimSpace(data)
|
||||
return strconv.ParseUint(string(et), 10, 64)
|
||||
}
|
4
vendor/github.com/cilium/ebpf/link/raw_tracepoint.go
generated
vendored
4
vendor/github.com/cilium/ebpf/link/raw_tracepoint.go
generated
vendored
@ -55,3 +55,7 @@ func (rt *progAttachRawTracepoint) Update(_ *ebpf.Program) error {
|
||||
func (rt *progAttachRawTracepoint) Pin(_ string) error {
|
||||
return fmt.Errorf("can't pin raw_tracepoint: %w", ErrNotSupported)
|
||||
}
|
||||
|
||||
func (rt *progAttachRawTracepoint) Unpin() error {
|
||||
return fmt.Errorf("unpin raw_tracepoint: %w", ErrNotSupported)
|
||||
}
|
||||
|
56
vendor/github.com/cilium/ebpf/link/tracepoint.go
generated
vendored
Normal file
56
vendor/github.com/cilium/ebpf/link/tracepoint.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
package link
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cilium/ebpf"
|
||||
)
|
||||
|
||||
// Tracepoint attaches the given eBPF program to the tracepoint with the given
|
||||
// group and name. See /sys/kernel/debug/tracing/events to find available
|
||||
// tracepoints. The top-level directory is the group, the event's subdirectory
|
||||
// is the name. Example:
|
||||
//
|
||||
// Tracepoint("syscalls", "sys_enter_fork")
|
||||
//
|
||||
// Note that attaching eBPF programs to syscalls (sys_enter_*/sys_exit_*) is
|
||||
// only possible as of kernel 4.14 (commit cf5f5ce).
|
||||
func Tracepoint(group, name string, prog *ebpf.Program) (Link, error) {
|
||||
if group == "" || name == "" {
|
||||
return nil, fmt.Errorf("group and name cannot be empty: %w", errInvalidInput)
|
||||
}
|
||||
if prog == nil {
|
||||
return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput)
|
||||
}
|
||||
if !rgxTraceEvent.MatchString(group) || !rgxTraceEvent.MatchString(name) {
|
||||
return nil, fmt.Errorf("group and name '%s/%s' must be alphanumeric or underscore: %w", group, name, errInvalidInput)
|
||||
}
|
||||
if prog.Type() != ebpf.TracePoint {
|
||||
return nil, fmt.Errorf("eBPF program type %s is not a Tracepoint: %w", prog.Type(), errInvalidInput)
|
||||
}
|
||||
|
||||
tid, err := getTraceEventID(group, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fd, err := openTracepointPerfEvent(tid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pe := &perfEvent{
|
||||
fd: fd,
|
||||
tracefsID: tid,
|
||||
group: group,
|
||||
name: name,
|
||||
progType: ebpf.TracePoint,
|
||||
}
|
||||
|
||||
if err := pe.attach(prog); err != nil {
|
||||
pe.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pe, nil
|
||||
}
|
54
vendor/github.com/cilium/ebpf/map.go
generated
vendored
54
vendor/github.com/cilium/ebpf/map.go
generated
vendored
@ -25,7 +25,8 @@ type MapOptions struct {
|
||||
// The base path to pin maps in if requested via PinByName.
|
||||
// Existing maps will be re-used if they are compatible, otherwise an
|
||||
// error is returned.
|
||||
PinPath string
|
||||
PinPath string
|
||||
LoadPinOptions LoadPinOptions
|
||||
}
|
||||
|
||||
// MapID represents the unique ID of an eBPF map
|
||||
@ -40,7 +41,10 @@ type MapSpec struct {
|
||||
KeySize uint32
|
||||
ValueSize uint32
|
||||
MaxEntries uint32
|
||||
Flags uint32
|
||||
|
||||
// Flags is passed to the kernel and specifies additional map
|
||||
// creation attributes.
|
||||
Flags uint32
|
||||
|
||||
// Automatically pin and load a map from MapOptions.PinPath.
|
||||
// Generates an error if an existing pinned map is incompatible with the MapSpec.
|
||||
@ -174,23 +178,30 @@ func NewMapWithOptions(spec *MapSpec, opts MapOptions) (*Map, error) {
|
||||
return newMapWithOptions(spec, opts, btfs)
|
||||
}
|
||||
|
||||
func newMapWithOptions(spec *MapSpec, opts MapOptions, btfs btfHandleCache) (*Map, error) {
|
||||
func newMapWithOptions(spec *MapSpec, opts MapOptions, btfs btfHandleCache) (_ *Map, err error) {
|
||||
closeOnError := func(c io.Closer) {
|
||||
if err != nil {
|
||||
c.Close()
|
||||
}
|
||||
}
|
||||
|
||||
switch spec.Pinning {
|
||||
case PinByName:
|
||||
if spec.Name == "" || opts.PinPath == "" {
|
||||
return nil, fmt.Errorf("pin by name: missing Name or PinPath")
|
||||
}
|
||||
|
||||
m, err := LoadPinnedMap(filepath.Join(opts.PinPath, spec.Name))
|
||||
path := filepath.Join(opts.PinPath, spec.Name)
|
||||
m, err := LoadPinnedMap(path, &opts.LoadPinOptions)
|
||||
if errors.Is(err, unix.ENOENT) {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load pinned map: %s", err)
|
||||
return nil, fmt.Errorf("load pinned map: %w", err)
|
||||
}
|
||||
defer closeOnError(m)
|
||||
|
||||
if err := spec.checkCompatibility(m); err != nil {
|
||||
m.Close()
|
||||
return nil, fmt.Errorf("use pinned map %s: %s", spec.Name, err)
|
||||
}
|
||||
|
||||
@ -226,10 +237,11 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, btfs btfHandleCache) (*Ma
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer closeOnError(m)
|
||||
|
||||
if spec.Pinning == PinByName {
|
||||
if err := m.Pin(filepath.Join(opts.PinPath, spec.Name)); err != nil {
|
||||
m.Close()
|
||||
path := filepath.Join(opts.PinPath, spec.Name)
|
||||
if err := m.Pin(path); err != nil {
|
||||
return nil, fmt.Errorf("pin map: %s", err)
|
||||
}
|
||||
}
|
||||
@ -805,12 +817,13 @@ func (m *Map) Clone() (*Map, error) {
|
||||
// Pin persists the map on the BPF virtual file system past the lifetime of
|
||||
// the process that created it .
|
||||
//
|
||||
// Calling Pin on a previously pinned map will override the path.
|
||||
// Calling Pin on a previously pinned map will overwrite the path, except when
|
||||
// the new path already exists. Re-pinning across filesystems is not supported.
|
||||
// You can Clone a map to pin it to a different path.
|
||||
//
|
||||
// This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs
|
||||
func (m *Map) Pin(fileName string) error {
|
||||
if err := pin(m.pinnedPath, fileName, m.fd); err != nil {
|
||||
if err := internal.Pin(m.pinnedPath, fileName, m.fd); err != nil {
|
||||
return err
|
||||
}
|
||||
m.pinnedPath = fileName
|
||||
@ -823,7 +836,7 @@ func (m *Map) Pin(fileName string) error {
|
||||
//
|
||||
// Unpinning an unpinned Map returns nil.
|
||||
func (m *Map) Unpin() error {
|
||||
if err := unpin(m.pinnedPath); err != nil {
|
||||
if err := internal.Unpin(m.pinnedPath); err != nil {
|
||||
return err
|
||||
}
|
||||
m.pinnedPath = ""
|
||||
@ -832,10 +845,7 @@ func (m *Map) Unpin() error {
|
||||
|
||||
// IsPinned returns true if the map has a non-empty pinned path.
|
||||
func (m *Map) IsPinned() bool {
|
||||
if m.pinnedPath == "" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return m.pinnedPath != ""
|
||||
}
|
||||
|
||||
// Freeze prevents a map to be modified from user space.
|
||||
@ -937,7 +947,9 @@ func (m *Map) unmarshalValue(value interface{}, buf []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
(*value).Close()
|
||||
// The caller might close the map externally, so ignore errors.
|
||||
_ = (*value).Close()
|
||||
|
||||
*value = other
|
||||
return nil
|
||||
|
||||
@ -957,7 +969,9 @@ func (m *Map) unmarshalValue(value interface{}, buf []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
(*value).Close()
|
||||
// The caller might close the program externally, so ignore errors.
|
||||
_ = (*value).Close()
|
||||
|
||||
*value = other
|
||||
return nil
|
||||
|
||||
@ -971,9 +985,9 @@ func (m *Map) unmarshalValue(value interface{}, buf []byte) error {
|
||||
return unmarshalBytes(value, buf)
|
||||
}
|
||||
|
||||
// LoadPinnedMap load a Map from a BPF file.
|
||||
func LoadPinnedMap(fileName string) (*Map, error) {
|
||||
fd, err := internal.BPFObjGet(fileName)
|
||||
// LoadPinnedMap loads a Map from a BPF file.
|
||||
func LoadPinnedMap(fileName string, opts *LoadPinOptions) (*Map, error) {
|
||||
fd, err := internal.BPFObjGet(fileName, opts.Marshal())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
4
vendor/github.com/cilium/ebpf/marshalers.go
generated
vendored
4
vendor/github.com/cilium/ebpf/marshalers.go
generated
vendored
@ -84,7 +84,9 @@ func makeBuffer(dst interface{}, length int) (internal.Pointer, []byte) {
|
||||
func unmarshalBytes(data interface{}, buf []byte) error {
|
||||
switch value := data.(type) {
|
||||
case unsafe.Pointer:
|
||||
sh := &reflect.SliceHeader{
|
||||
// This could be solved in Go 1.17 by unsafe.Slice instead. (https://github.com/golang/go/issues/19367)
|
||||
// We could opt for removing unsafe.Pointer support in the lib as well.
|
||||
sh := &reflect.SliceHeader{ //nolint:govet
|
||||
Data: uintptr(value),
|
||||
Len: len(buf),
|
||||
Cap: len(buf),
|
||||
|
43
vendor/github.com/cilium/ebpf/prog.go
generated
vendored
43
vendor/github.com/cilium/ebpf/prog.go
generated
vendored
@ -55,16 +55,19 @@ type ProgramSpec struct {
|
||||
// depends on Type and AttachType.
|
||||
AttachTo string
|
||||
Instructions asm.Instructions
|
||||
|
||||
// Flags is passed to the kernel and specifies additional program
|
||||
// load attributes.
|
||||
Flags uint32
|
||||
// License of the program. Some helpers are only available if
|
||||
// the license is deemed compatible with the GPL.
|
||||
//
|
||||
// See https://www.kernel.org/doc/html/latest/process/license-rules.html#id1
|
||||
License string
|
||||
|
||||
// Version used by tracing programs.
|
||||
// Version used by Kprobe programs.
|
||||
//
|
||||
// Deprecated: superseded by BTF.
|
||||
// Deprecated on kernels 5.0 and later. Leave empty to let the library
|
||||
// detect this value automatically.
|
||||
KernelVersion uint32
|
||||
|
||||
// The BTF associated with this program. Changing Instructions
|
||||
@ -141,6 +144,19 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, btfs btfHandl
|
||||
return nil, fmt.Errorf("can't load %s program on %s", spec.ByteOrder, internal.NativeEndian)
|
||||
}
|
||||
|
||||
// Kernels before 5.0 (6c4fc209fcf9 "bpf: remove useless version check for prog load")
|
||||
// require the version field to be set to the value of the KERNEL_VERSION
|
||||
// macro for kprobe-type programs.
|
||||
// Overwrite Kprobe program version if set to zero or the magic version constant.
|
||||
kv := spec.KernelVersion
|
||||
if spec.Type == Kprobe && (kv == 0 || kv == internal.MagicKernelVersion) {
|
||||
v, err := internal.KernelVersion()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("detecting kernel version: %w", err)
|
||||
}
|
||||
kv = v.Kernel()
|
||||
}
|
||||
|
||||
insns := make(asm.Instructions, len(spec.Instructions))
|
||||
copy(insns, spec.Instructions)
|
||||
|
||||
@ -158,11 +174,12 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, btfs btfHandl
|
||||
insCount := uint32(len(bytecode) / asm.InstructionSize)
|
||||
attr := &bpfProgLoadAttr{
|
||||
progType: spec.Type,
|
||||
progFlags: spec.Flags,
|
||||
expectedAttachType: spec.AttachType,
|
||||
insCount: insCount,
|
||||
instructions: internal.NewSlicePointer(bytecode),
|
||||
license: internal.NewStringPointer(spec.License),
|
||||
kernelVersion: spec.KernelVersion,
|
||||
kernelVersion: kv,
|
||||
}
|
||||
|
||||
if haveObjName() == nil {
|
||||
@ -345,9 +362,12 @@ func (p *Program) Clone() (*Program, error) {
|
||||
// Pin persists the Program on the BPF virtual file system past the lifetime of
|
||||
// the process that created it
|
||||
//
|
||||
// Calling Pin on a previously pinned program will overwrite the path, except when
|
||||
// the new path already exists. Re-pinning across filesystems is not supported.
|
||||
//
|
||||
// This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs
|
||||
func (p *Program) Pin(fileName string) error {
|
||||
if err := pin(p.pinnedPath, fileName, p.fd); err != nil {
|
||||
if err := internal.Pin(p.pinnedPath, fileName, p.fd); err != nil {
|
||||
return err
|
||||
}
|
||||
p.pinnedPath = fileName
|
||||
@ -360,7 +380,7 @@ func (p *Program) Pin(fileName string) error {
|
||||
//
|
||||
// Unpinning an unpinned Program returns nil.
|
||||
func (p *Program) Unpin() error {
|
||||
if err := unpin(p.pinnedPath); err != nil {
|
||||
if err := internal.Unpin(p.pinnedPath); err != nil {
|
||||
return err
|
||||
}
|
||||
p.pinnedPath = ""
|
||||
@ -369,10 +389,7 @@ func (p *Program) Unpin() error {
|
||||
|
||||
// IsPinned returns true if the Program has a non-empty pinned path.
|
||||
func (p *Program) IsPinned() bool {
|
||||
if p.pinnedPath == "" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return p.pinnedPath != ""
|
||||
}
|
||||
|
||||
// Close unloads the program from the kernel.
|
||||
@ -597,8 +614,8 @@ func (p *Program) Detach(fd int, typ AttachType, flags AttachFlags) error {
|
||||
// LoadPinnedProgram loads a Program from a BPF file.
|
||||
//
|
||||
// Requires at least Linux 4.11.
|
||||
func LoadPinnedProgram(fileName string) (*Program, error) {
|
||||
fd, err := internal.BPFObjGet(fileName)
|
||||
func LoadPinnedProgram(fileName string, opts *LoadPinOptions) (*Program, error) {
|
||||
fd, err := internal.BPFObjGet(fileName, opts.Marshal())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -609,7 +626,7 @@ func LoadPinnedProgram(fileName string) (*Program, error) {
|
||||
return nil, fmt.Errorf("info for %s: %w", fileName, err)
|
||||
}
|
||||
|
||||
return &Program{"", fd, filepath.Base(fileName), "", info.Type}, nil
|
||||
return &Program{"", fd, filepath.Base(fileName), fileName, info.Type}, nil
|
||||
}
|
||||
|
||||
// SanitizeName replaces all invalid characters in name with replacement.
|
||||
|
1
vendor/github.com/cilium/ebpf/run-tests.sh
generated
vendored
1
vendor/github.com/cilium/ebpf/run-tests.sh
generated
vendored
@ -9,6 +9,7 @@ if [[ "${1:-}" = "--in-vm" ]]; then
|
||||
shift
|
||||
|
||||
mount -t bpf bpf /sys/fs/bpf
|
||||
mount -t tracefs tracefs /sys/kernel/debug/tracing
|
||||
export CGO_ENABLED=0
|
||||
export GOFLAGS=-mod=readonly
|
||||
export GOPATH=/run/go-path
|
||||
|
2
vendor/github.com/cilium/ebpf/syscalls.go
generated
vendored
2
vendor/github.com/cilium/ebpf/syscalls.go
generated
vendored
@ -383,7 +383,7 @@ func wrapMapError(err error) error {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
return errors.New(err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
func bpfMapFreeze(m *internal.FD) error {
|
||||
|
31
vendor/github.com/cilium/ebpf/types.go
generated
vendored
31
vendor/github.com/cilium/ebpf/types.go
generated
vendored
@ -1,5 +1,9 @@
|
||||
package ebpf
|
||||
|
||||
import (
|
||||
"github.com/cilium/ebpf/internal/unix"
|
||||
)
|
||||
|
||||
//go:generate stringer -output types_string.go -type=MapType,ProgramType,AttachType,PinType
|
||||
|
||||
// MapType indicates the type map structure
|
||||
@ -202,6 +206,33 @@ const (
|
||||
PinByName
|
||||
)
|
||||
|
||||
// LoadPinOptions control how a pinned object is loaded.
|
||||
type LoadPinOptions struct {
|
||||
// Request a read-only or write-only object. The default is a read-write
|
||||
// object. Only one of the flags may be set.
|
||||
ReadOnly bool
|
||||
WriteOnly bool
|
||||
|
||||
// Raw flags for the syscall. Other fields of this struct take precedence.
|
||||
Flags uint32
|
||||
}
|
||||
|
||||
// Marshal returns a value suitable for BPF_OBJ_GET syscall file_flags parameter.
|
||||
func (lpo *LoadPinOptions) Marshal() uint32 {
|
||||
if lpo == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
flags := lpo.Flags
|
||||
if lpo.ReadOnly {
|
||||
flags |= unix.BPF_F_RDONLY
|
||||
}
|
||||
if lpo.WriteOnly {
|
||||
flags |= unix.BPF_F_WRONLY
|
||||
}
|
||||
return flags
|
||||
}
|
||||
|
||||
// BatchOptions batch map operations options
|
||||
//
|
||||
// Mirrors libbpf struct bpf_map_batch_opts
|
||||
|
45
vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go
generated
vendored
45
vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go
generated
vendored
@ -16,6 +16,7 @@
|
||||
package dbus
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
@ -112,39 +113,63 @@ type Conn struct {
|
||||
|
||||
// New establishes a connection to any available bus and authenticates.
|
||||
// Callers should call Close() when done with the connection.
|
||||
// Deprecated: use NewWithContext instead
|
||||
func New() (*Conn, error) {
|
||||
conn, err := NewSystemConnection()
|
||||
return NewWithContext(context.Background())
|
||||
}
|
||||
|
||||
// NewWithContext same as New with context
|
||||
func NewWithContext(ctx context.Context) (*Conn, error) {
|
||||
conn, err := NewSystemConnectionContext(ctx)
|
||||
if err != nil && os.Geteuid() == 0 {
|
||||
return NewSystemdConnection()
|
||||
return NewSystemdConnectionContext(ctx)
|
||||
}
|
||||
return conn, err
|
||||
}
|
||||
|
||||
// NewSystemConnection establishes a connection to the system bus and authenticates.
|
||||
// Callers should call Close() when done with the connection
|
||||
// Deprecated: use NewSystemConnectionContext instead
|
||||
func NewSystemConnection() (*Conn, error) {
|
||||
return NewSystemConnectionContext(context.Background())
|
||||
}
|
||||
|
||||
// NewSystemConnectionContext same as NewSystemConnection with context
|
||||
func NewSystemConnectionContext(ctx context.Context) (*Conn, error) {
|
||||
return NewConnection(func() (*dbus.Conn, error) {
|
||||
return dbusAuthHelloConnection(dbus.SystemBusPrivate)
|
||||
return dbusAuthHelloConnection(ctx, dbus.SystemBusPrivate)
|
||||
})
|
||||
}
|
||||
|
||||
// NewUserConnection establishes a connection to the session bus and
|
||||
// authenticates. This can be used to connect to systemd user instances.
|
||||
// Callers should call Close() when done with the connection.
|
||||
// Deprecated: use NewUserConnectionContext instead
|
||||
func NewUserConnection() (*Conn, error) {
|
||||
return NewUserConnectionContext(context.Background())
|
||||
}
|
||||
|
||||
// NewUserConnectionContext same as NewUserConnection with context
|
||||
func NewUserConnectionContext(ctx context.Context) (*Conn, error) {
|
||||
return NewConnection(func() (*dbus.Conn, error) {
|
||||
return dbusAuthHelloConnection(dbus.SessionBusPrivate)
|
||||
return dbusAuthHelloConnection(ctx, dbus.SessionBusPrivate)
|
||||
})
|
||||
}
|
||||
|
||||
// NewSystemdConnection establishes a private, direct connection to systemd.
|
||||
// This can be used for communicating with systemd without a dbus daemon.
|
||||
// Callers should call Close() when done with the connection.
|
||||
// Deprecated: use NewSystemdConnectionContext instead
|
||||
func NewSystemdConnection() (*Conn, error) {
|
||||
return NewSystemdConnectionContext(context.Background())
|
||||
}
|
||||
|
||||
// NewSystemdConnectionContext same as NewSystemdConnection with context
|
||||
func NewSystemdConnectionContext(ctx context.Context) (*Conn, error) {
|
||||
return NewConnection(func() (*dbus.Conn, error) {
|
||||
// We skip Hello when talking directly to systemd.
|
||||
return dbusAuthConnection(func(opts ...dbus.ConnOption) (*dbus.Conn, error) {
|
||||
return dbus.Dial("unix:path=/run/systemd/private")
|
||||
return dbusAuthConnection(ctx, func(opts ...dbus.ConnOption) (*dbus.Conn, error) {
|
||||
return dbus.Dial("unix:path=/run/systemd/private", opts...)
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -201,8 +226,8 @@ func (c *Conn) GetManagerProperty(prop string) (string, error) {
|
||||
return variant.String(), nil
|
||||
}
|
||||
|
||||
func dbusAuthConnection(createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) {
|
||||
conn, err := createBus()
|
||||
func dbusAuthConnection(ctx context.Context, createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) {
|
||||
conn, err := createBus(dbus.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -221,8 +246,8 @@ func dbusAuthConnection(createBus func(opts ...dbus.ConnOption) (*dbus.Conn, err
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func dbusAuthHelloConnection(createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) {
|
||||
conn, err := dbusAuthConnection(createBus)
|
||||
func dbusAuthHelloConnection(ctx context.Context, createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) {
|
||||
conn, err := dbusAuthConnection(ctx, createBus)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
325
vendor/github.com/coreos/go-systemd/v22/dbus/methods.go
generated
vendored
325
vendor/github.com/coreos/go-systemd/v22/dbus/methods.go
generated
vendored
@ -15,6 +15,7 @@
|
||||
package dbus
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
@ -23,6 +24,18 @@ import (
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
// Who can be used to specify which process to kill in the unit via the KillUnitWithTarget API
|
||||
type Who string
|
||||
|
||||
const (
|
||||
// All sends the signal to all processes in the unit
|
||||
All Who = "all"
|
||||
// Main sends the signal to the main process of the unit
|
||||
Main Who = "main"
|
||||
// Control sends the signal to the control process of the unit
|
||||
Control Who = "control"
|
||||
)
|
||||
|
||||
func (c *Conn) jobComplete(signal *dbus.Signal) {
|
||||
var id uint32
|
||||
var job dbus.ObjectPath
|
||||
@ -38,14 +51,14 @@ func (c *Conn) jobComplete(signal *dbus.Signal) {
|
||||
c.jobListener.Unlock()
|
||||
}
|
||||
|
||||
func (c *Conn) startJob(ch chan<- string, job string, args ...interface{}) (int, error) {
|
||||
func (c *Conn) startJob(ctx context.Context, ch chan<- string, job string, args ...interface{}) (int, error) {
|
||||
if ch != nil {
|
||||
c.jobListener.Lock()
|
||||
defer c.jobListener.Unlock()
|
||||
}
|
||||
|
||||
var p dbus.ObjectPath
|
||||
err := c.sysobj.Call(job, 0, args...).Store(&p)
|
||||
err := c.sysobj.CallWithContext(ctx, job, 0, args...).Store(&p)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -90,43 +103,85 @@ func (c *Conn) startJob(ch chan<- string, job string, args ...interface{}) (int,
|
||||
// should not be considered authoritative.
|
||||
//
|
||||
// If an error does occur, it will be returned to the user alongside a job ID of 0.
|
||||
// Deprecated: use StartUnitContext instead
|
||||
func (c *Conn) StartUnit(name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ch, "org.freedesktop.systemd1.Manager.StartUnit", name, mode)
|
||||
return c.StartUnitContext(context.Background(), name, mode, ch)
|
||||
}
|
||||
|
||||
// StartUnitContext same as StartUnit with context
|
||||
func (c *Conn) StartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StartUnit", name, mode)
|
||||
}
|
||||
|
||||
// StopUnit is similar to StartUnit but stops the specified unit rather
|
||||
// than starting it.
|
||||
// Deprecated: use StopUnitContext instead
|
||||
func (c *Conn) StopUnit(name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ch, "org.freedesktop.systemd1.Manager.StopUnit", name, mode)
|
||||
return c.StopUnitContext(context.Background(), name, mode, ch)
|
||||
}
|
||||
|
||||
// StopUnitContext same as StopUnit with context
|
||||
func (c *Conn) StopUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StopUnit", name, mode)
|
||||
}
|
||||
|
||||
// ReloadUnit reloads a unit. Reloading is done only if the unit is already running and fails otherwise.
|
||||
// Deprecated: use ReloadUnitContext instead
|
||||
func (c *Conn) ReloadUnit(name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ch, "org.freedesktop.systemd1.Manager.ReloadUnit", name, mode)
|
||||
return c.ReloadUnitContext(context.Background(), name, mode, ch)
|
||||
}
|
||||
|
||||
// ReloadUnitContext same as ReloadUnit with context
|
||||
func (c *Conn) ReloadUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadUnit", name, mode)
|
||||
}
|
||||
|
||||
// RestartUnit restarts a service. If a service is restarted that isn't
|
||||
// running it will be started.
|
||||
// Deprecated: use RestartUnitContext instead
|
||||
func (c *Conn) RestartUnit(name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ch, "org.freedesktop.systemd1.Manager.RestartUnit", name, mode)
|
||||
return c.RestartUnitContext(context.Background(), name, mode, ch)
|
||||
}
|
||||
|
||||
// RestartUnitContext same as RestartUnit with context
|
||||
func (c *Conn) RestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.RestartUnit", name, mode)
|
||||
}
|
||||
|
||||
// TryRestartUnit is like RestartUnit, except that a service that isn't running
|
||||
// is not affected by the restart.
|
||||
// Deprecated: use TryRestartUnitContext instead
|
||||
func (c *Conn) TryRestartUnit(name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ch, "org.freedesktop.systemd1.Manager.TryRestartUnit", name, mode)
|
||||
return c.TryRestartUnitContext(context.Background(), name, mode, ch)
|
||||
}
|
||||
|
||||
// TryRestartUnitContext same as TryRestartUnit with context
|
||||
func (c *Conn) TryRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.TryRestartUnit", name, mode)
|
||||
}
|
||||
|
||||
// ReloadOrRestartUnit attempts a reload if the unit supports it and use a restart
|
||||
// otherwise.
|
||||
// Deprecated: use ReloadOrRestartUnitContext instead
|
||||
func (c *Conn) ReloadOrRestartUnit(name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ch, "org.freedesktop.systemd1.Manager.ReloadOrRestartUnit", name, mode)
|
||||
return c.ReloadOrRestartUnitContext(context.Background(), name, mode, ch)
|
||||
}
|
||||
|
||||
// ReloadOrRestartUnitContext same as ReloadOrRestartUnit with context
|
||||
func (c *Conn) ReloadOrRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadOrRestartUnit", name, mode)
|
||||
}
|
||||
|
||||
// ReloadOrTryRestartUnit attempts a reload if the unit supports it and use a "Try"
|
||||
// flavored restart otherwise.
|
||||
// Deprecated: use ReloadOrTryRestartUnitContext instead
|
||||
func (c *Conn) ReloadOrTryRestartUnit(name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ch, "org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit", name, mode)
|
||||
return c.ReloadOrTryRestartUnitContext(context.Background(), name, mode, ch)
|
||||
}
|
||||
|
||||
// ReloadOrTryRestartUnitContext same as ReloadOrTryRestartUnit with context
|
||||
func (c *Conn) ReloadOrTryRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) {
|
||||
return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit", name, mode)
|
||||
}
|
||||
|
||||
// StartTransientUnit() may be used to create and start a transient unit, which
|
||||
@ -134,28 +189,57 @@ func (c *Conn) ReloadOrTryRestartUnit(name string, mode string, ch chan<- string
|
||||
// system is rebooted. name is the unit name including suffix, and must be
|
||||
// unique. mode is the same as in StartUnit(), properties contains properties
|
||||
// of the unit.
|
||||
// Deprecated: use StartTransientUnitContext instead
|
||||
func (c *Conn) StartTransientUnit(name string, mode string, properties []Property, ch chan<- string) (int, error) {
|
||||
return c.startJob(ch, "org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]PropertyCollection, 0))
|
||||
return c.StartTransientUnitContext(context.Background(), name, mode, properties, ch)
|
||||
}
|
||||
|
||||
// StartTransientUnitContext same as StartTransientUnit with context
|
||||
func (c *Conn) StartTransientUnitContext(ctx context.Context, name string, mode string, properties []Property, ch chan<- string) (int, error) {
|
||||
return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]PropertyCollection, 0))
|
||||
}
|
||||
|
||||
// KillUnit takes the unit name and a UNIX signal number to send. All of the unit's
|
||||
// processes are killed.
|
||||
// Deprecated: use KillUnitContext instead
|
||||
func (c *Conn) KillUnit(name string, signal int32) {
|
||||
c.sysobj.Call("org.freedesktop.systemd1.Manager.KillUnit", 0, name, "all", signal).Store()
|
||||
c.KillUnitContext(context.Background(), name, signal)
|
||||
}
|
||||
|
||||
// KillUnitContext same as KillUnit with context
|
||||
func (c *Conn) KillUnitContext(ctx context.Context, name string, signal int32) {
|
||||
c.KillUnitWithTarget(ctx, name, All, signal)
|
||||
}
|
||||
|
||||
// KillUnitWithTarget is like KillUnitContext, but allows you to specify which process in the unit to send the signal to
|
||||
func (c *Conn) KillUnitWithTarget(ctx context.Context, name string, target Who, signal int32) error {
|
||||
return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.KillUnit", 0, name, string(target), signal).Store()
|
||||
}
|
||||
|
||||
// ResetFailedUnit resets the "failed" state of a specific unit.
|
||||
// Deprecated: use ResetFailedUnitContext instead
|
||||
func (c *Conn) ResetFailedUnit(name string) error {
|
||||
return c.sysobj.Call("org.freedesktop.systemd1.Manager.ResetFailedUnit", 0, name).Store()
|
||||
return c.ResetFailedUnitContext(context.Background(), name)
|
||||
}
|
||||
|
||||
// ResetFailedUnitContext same as ResetFailedUnit with context
|
||||
func (c *Conn) ResetFailedUnitContext(ctx context.Context, name string) error {
|
||||
return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ResetFailedUnit", 0, name).Store()
|
||||
}
|
||||
|
||||
// SystemState returns the systemd state. Equivalent to `systemctl is-system-running`.
|
||||
// Deprecated: use SystemStateContext instead
|
||||
func (c *Conn) SystemState() (*Property, error) {
|
||||
return c.SystemStateContext(context.Background())
|
||||
}
|
||||
|
||||
// SystemStateContext same as SystemState with context
|
||||
func (c *Conn) SystemStateContext(ctx context.Context) (*Property, error) {
|
||||
var err error
|
||||
var prop dbus.Variant
|
||||
|
||||
obj := c.sysconn.Object("org.freedesktop.systemd1", "/org/freedesktop/systemd1")
|
||||
err = obj.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.systemd1.Manager", "SystemState").Store(&prop)
|
||||
err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.systemd1.Manager", "SystemState").Store(&prop)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -164,7 +248,7 @@ func (c *Conn) SystemState() (*Property, error) {
|
||||
}
|
||||
|
||||
// getProperties takes the unit path and returns all of its dbus object properties, for the given dbus interface
|
||||
func (c *Conn) getProperties(path dbus.ObjectPath, dbusInterface string) (map[string]interface{}, error) {
|
||||
func (c *Conn) getProperties(ctx context.Context, path dbus.ObjectPath, dbusInterface string) (map[string]interface{}, error) {
|
||||
var err error
|
||||
var props map[string]dbus.Variant
|
||||
|
||||
@ -173,7 +257,7 @@ func (c *Conn) getProperties(path dbus.ObjectPath, dbusInterface string) (map[st
|
||||
}
|
||||
|
||||
obj := c.sysconn.Object("org.freedesktop.systemd1", path)
|
||||
err = obj.Call("org.freedesktop.DBus.Properties.GetAll", 0, dbusInterface).Store(&props)
|
||||
err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.GetAll", 0, dbusInterface).Store(&props)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -187,23 +271,41 @@ func (c *Conn) getProperties(path dbus.ObjectPath, dbusInterface string) (map[st
|
||||
}
|
||||
|
||||
// GetUnitProperties takes the (unescaped) unit name and returns all of its dbus object properties.
|
||||
// Deprecated: use GetUnitPropertiesContext instead
|
||||
func (c *Conn) GetUnitProperties(unit string) (map[string]interface{}, error) {
|
||||
return c.GetUnitPropertiesContext(context.Background(), unit)
|
||||
}
|
||||
|
||||
// GetUnitPropertiesContext same as GetUnitPropertiesContext with context
|
||||
func (c *Conn) GetUnitPropertiesContext(ctx context.Context, unit string) (map[string]interface{}, error) {
|
||||
path := unitPath(unit)
|
||||
return c.getProperties(path, "org.freedesktop.systemd1.Unit")
|
||||
return c.getProperties(ctx, path, "org.freedesktop.systemd1.Unit")
|
||||
}
|
||||
|
||||
// GetUnitPathProperties takes the (escaped) unit path and returns all of its dbus object properties.
|
||||
// Deprecated: use GetUnitPathPropertiesContext instead
|
||||
func (c *Conn) GetUnitPathProperties(path dbus.ObjectPath) (map[string]interface{}, error) {
|
||||
return c.getProperties(path, "org.freedesktop.systemd1.Unit")
|
||||
return c.GetUnitPathPropertiesContext(context.Background(), path)
|
||||
}
|
||||
|
||||
// GetUnitPathPropertiesContext same as GetUnitPathProperties with context
|
||||
func (c *Conn) GetUnitPathPropertiesContext(ctx context.Context, path dbus.ObjectPath) (map[string]interface{}, error) {
|
||||
return c.getProperties(ctx, path, "org.freedesktop.systemd1.Unit")
|
||||
}
|
||||
|
||||
// GetAllProperties takes the (unescaped) unit name and returns all of its dbus object properties.
|
||||
// Deprecated: use GetAllPropertiesContext instead
|
||||
func (c *Conn) GetAllProperties(unit string) (map[string]interface{}, error) {
|
||||
path := unitPath(unit)
|
||||
return c.getProperties(path, "")
|
||||
return c.GetAllPropertiesContext(context.Background(), unit)
|
||||
}
|
||||
|
||||
func (c *Conn) getProperty(unit string, dbusInterface string, propertyName string) (*Property, error) {
|
||||
// GetAllPropertiesContext same as GetAllProperties with context
|
||||
func (c *Conn) GetAllPropertiesContext(ctx context.Context, unit string) (map[string]interface{}, error) {
|
||||
path := unitPath(unit)
|
||||
return c.getProperties(ctx, path, "")
|
||||
}
|
||||
|
||||
func (c *Conn) getProperty(ctx context.Context, unit string, dbusInterface string, propertyName string) (*Property, error) {
|
||||
var err error
|
||||
var prop dbus.Variant
|
||||
|
||||
@ -213,7 +315,7 @@ func (c *Conn) getProperty(unit string, dbusInterface string, propertyName strin
|
||||
}
|
||||
|
||||
obj := c.sysconn.Object("org.freedesktop.systemd1", path)
|
||||
err = obj.Call("org.freedesktop.DBus.Properties.Get", 0, dbusInterface, propertyName).Store(&prop)
|
||||
err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, dbusInterface, propertyName).Store(&prop)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -221,21 +323,39 @@ func (c *Conn) getProperty(unit string, dbusInterface string, propertyName strin
|
||||
return &Property{Name: propertyName, Value: prop}, nil
|
||||
}
|
||||
|
||||
// Deprecated: use GetUnitPropertyContext instead
|
||||
func (c *Conn) GetUnitProperty(unit string, propertyName string) (*Property, error) {
|
||||
return c.getProperty(unit, "org.freedesktop.systemd1.Unit", propertyName)
|
||||
return c.GetUnitPropertyContext(context.Background(), unit, propertyName)
|
||||
}
|
||||
|
||||
// GetUnitPropertyContext same as GetUnitProperty with context
|
||||
func (c *Conn) GetUnitPropertyContext(ctx context.Context, unit string, propertyName string) (*Property, error) {
|
||||
return c.getProperty(ctx, unit, "org.freedesktop.systemd1.Unit", propertyName)
|
||||
}
|
||||
|
||||
// GetServiceProperty returns property for given service name and property name
|
||||
// Deprecated: use GetServicePropertyContext instead
|
||||
func (c *Conn) GetServiceProperty(service string, propertyName string) (*Property, error) {
|
||||
return c.getProperty(service, "org.freedesktop.systemd1.Service", propertyName)
|
||||
return c.GetServicePropertyContext(context.Background(), service, propertyName)
|
||||
}
|
||||
|
||||
// GetServicePropertyContext same as GetServiceProperty with context
|
||||
func (c *Conn) GetServicePropertyContext(ctx context.Context, service string, propertyName string) (*Property, error) {
|
||||
return c.getProperty(ctx, service, "org.freedesktop.systemd1.Service", propertyName)
|
||||
}
|
||||
|
||||
// GetUnitTypeProperties returns the extra properties for a unit, specific to the unit type.
|
||||
// Valid values for unitType: Service, Socket, Target, Device, Mount, Automount, Snapshot, Timer, Swap, Path, Slice, Scope
|
||||
// return "dbus.Error: Unknown interface" if the unitType is not the correct type of the unit
|
||||
// Deprecated: use GetUnitTypePropertiesContext instead
|
||||
func (c *Conn) GetUnitTypeProperties(unit string, unitType string) (map[string]interface{}, error) {
|
||||
return c.GetUnitTypePropertiesContext(context.Background(), unit, unitType)
|
||||
}
|
||||
|
||||
// GetUnitTypePropertiesContext same as GetUnitTypeProperties with context
|
||||
func (c *Conn) GetUnitTypePropertiesContext(ctx context.Context, unit string, unitType string) (map[string]interface{}, error) {
|
||||
path := unitPath(unit)
|
||||
return c.getProperties(path, "org.freedesktop.systemd1."+unitType)
|
||||
return c.getProperties(ctx, path, "org.freedesktop.systemd1."+unitType)
|
||||
}
|
||||
|
||||
// SetUnitProperties() may be used to modify certain unit properties at runtime.
|
||||
@ -245,12 +365,24 @@ func (c *Conn) GetUnitTypeProperties(unit string, unitType string) (map[string]i
|
||||
// case the settings only apply until the next reboot. name is the name of the unit
|
||||
// to modify. properties are the settings to set, encoded as an array of property
|
||||
// name and value pairs.
|
||||
// Deprecated: use SetUnitPropertiesContext instead
|
||||
func (c *Conn) SetUnitProperties(name string, runtime bool, properties ...Property) error {
|
||||
return c.sysobj.Call("org.freedesktop.systemd1.Manager.SetUnitProperties", 0, name, runtime, properties).Store()
|
||||
return c.SetUnitPropertiesContext(context.Background(), name, runtime, properties...)
|
||||
}
|
||||
|
||||
// SetUnitPropertiesContext same as SetUnitProperties with context
|
||||
func (c *Conn) SetUnitPropertiesContext(ctx context.Context, name string, runtime bool, properties ...Property) error {
|
||||
return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.SetUnitProperties", 0, name, runtime, properties).Store()
|
||||
}
|
||||
|
||||
// Deprecated: use GetUnitTypePropertyContext instead
|
||||
func (c *Conn) GetUnitTypeProperty(unit string, unitType string, propertyName string) (*Property, error) {
|
||||
return c.getProperty(unit, "org.freedesktop.systemd1."+unitType, propertyName)
|
||||
return c.GetUnitTypePropertyContext(context.Background(), unit, unitType, propertyName)
|
||||
}
|
||||
|
||||
// GetUnitTypePropertyContext same as GetUnitTypeProperty with context
|
||||
func (c *Conn) GetUnitTypePropertyContext(ctx context.Context, unit string, unitType string, propertyName string) (*Property, error) {
|
||||
return c.getProperty(ctx, unit, "org.freedesktop.systemd1."+unitType, propertyName)
|
||||
}
|
||||
|
||||
type UnitStatus struct {
|
||||
@ -299,22 +431,40 @@ func (c *Conn) listUnitsInternal(f storeFunc) ([]UnitStatus, error) {
|
||||
// be more unit names loaded than actual units behind them.
|
||||
// Also note that a unit is only loaded if it is active and/or enabled.
|
||||
// Units that are both disabled and inactive will thus not be returned.
|
||||
// Deprecated: use ListUnitsContext instead
|
||||
func (c *Conn) ListUnits() ([]UnitStatus, error) {
|
||||
return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnits", 0).Store)
|
||||
return c.ListUnitsContext(context.Background())
|
||||
}
|
||||
|
||||
// ListUnitsContext same as ListUnits with context
|
||||
func (c *Conn) ListUnitsContext(ctx context.Context) ([]UnitStatus, error) {
|
||||
return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnits", 0).Store)
|
||||
}
|
||||
|
||||
// ListUnitsFiltered returns an array with units filtered by state.
|
||||
// It takes a list of units' statuses to filter.
|
||||
// Deprecated: use ListUnitsFilteredContext instead
|
||||
func (c *Conn) ListUnitsFiltered(states []string) ([]UnitStatus, error) {
|
||||
return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitsFiltered", 0, states).Store)
|
||||
return c.ListUnitsFilteredContext(context.Background(), states)
|
||||
}
|
||||
|
||||
// ListUnitsFilteredContext same as ListUnitsFiltered with context
|
||||
func (c *Conn) ListUnitsFilteredContext(ctx context.Context, states []string) ([]UnitStatus, error) {
|
||||
return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsFiltered", 0, states).Store)
|
||||
}
|
||||
|
||||
// ListUnitsByPatterns returns an array with units.
|
||||
// It takes a list of units' statuses and names to filter.
|
||||
// Note that units may be known by multiple names at the same time,
|
||||
// and hence there might be more unit names loaded than actual units behind them.
|
||||
// Deprecated: use ListUnitsByPatternsContext instead
|
||||
func (c *Conn) ListUnitsByPatterns(states []string, patterns []string) ([]UnitStatus, error) {
|
||||
return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitsByPatterns", 0, states, patterns).Store)
|
||||
return c.ListUnitsByPatternsContext(context.Background(), states, patterns)
|
||||
}
|
||||
|
||||
// ListUnitsByPatternsContext same as ListUnitsByPatterns with context
|
||||
func (c *Conn) ListUnitsByPatternsContext(ctx context.Context, states []string, patterns []string) ([]UnitStatus, error) {
|
||||
return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsByPatterns", 0, states, patterns).Store)
|
||||
}
|
||||
|
||||
// ListUnitsByNames returns an array with units. It takes a list of units'
|
||||
@ -322,8 +472,14 @@ func (c *Conn) ListUnitsByPatterns(states []string, patterns []string) ([]UnitSt
|
||||
// method, this method returns statuses even for inactive or non-existing
|
||||
// units. Input array should contain exact unit names, but not patterns.
|
||||
// Note: Requires systemd v230 or higher
|
||||
// Deprecated: use ListUnitsByNamesContext instead
|
||||
func (c *Conn) ListUnitsByNames(units []string) ([]UnitStatus, error) {
|
||||
return c.listUnitsInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitsByNames", 0, units).Store)
|
||||
return c.ListUnitsByNamesContext(context.Background(), units)
|
||||
}
|
||||
|
||||
// ListUnitsByNamesContext same as ListUnitsByNames with context
|
||||
func (c *Conn) ListUnitsByNamesContext(ctx context.Context, units []string) ([]UnitStatus, error) {
|
||||
return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsByNames", 0, units).Store)
|
||||
}
|
||||
|
||||
type UnitFile struct {
|
||||
@ -358,13 +514,25 @@ func (c *Conn) listUnitFilesInternal(f storeFunc) ([]UnitFile, error) {
|
||||
}
|
||||
|
||||
// ListUnitFiles returns an array of all available units on disk.
|
||||
// Deprecated: use ListUnitFilesContext instead
|
||||
func (c *Conn) ListUnitFiles() ([]UnitFile, error) {
|
||||
return c.listUnitFilesInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitFiles", 0).Store)
|
||||
return c.ListUnitFilesContext(context.Background())
|
||||
}
|
||||
|
||||
// ListUnitFilesContext same as ListUnitFiles with context
|
||||
func (c *Conn) ListUnitFilesContext(ctx context.Context) ([]UnitFile, error) {
|
||||
return c.listUnitFilesInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitFiles", 0).Store)
|
||||
}
|
||||
|
||||
// ListUnitFilesByPatterns returns an array of all available units on disk matched the patterns.
|
||||
// Deprecated: use ListUnitFilesByPatternsContext instead
|
||||
func (c *Conn) ListUnitFilesByPatterns(states []string, patterns []string) ([]UnitFile, error) {
|
||||
return c.listUnitFilesInternal(c.sysobj.Call("org.freedesktop.systemd1.Manager.ListUnitFilesByPatterns", 0, states, patterns).Store)
|
||||
return c.ListUnitFilesByPatternsContext(context.Background(), states, patterns)
|
||||
}
|
||||
|
||||
// ListUnitFilesByPatternsContext same as ListUnitFilesByPatterns with context
|
||||
func (c *Conn) ListUnitFilesByPatternsContext(ctx context.Context, states []string, patterns []string) ([]UnitFile, error) {
|
||||
return c.listUnitFilesInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitFilesByPatterns", 0, states, patterns).Store)
|
||||
}
|
||||
|
||||
type LinkUnitFileChange EnableUnitFileChange
|
||||
@ -383,9 +551,15 @@ type LinkUnitFileChange EnableUnitFileChange
|
||||
// structures with three strings: the type of the change (one of symlink
|
||||
// or unlink), the file name of the symlink and the destination of the
|
||||
// symlink.
|
||||
// Deprecated: use LinkUnitFilesContext instead
|
||||
func (c *Conn) LinkUnitFiles(files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) {
|
||||
return c.LinkUnitFilesContext(context.Background(), files, runtime, force)
|
||||
}
|
||||
|
||||
// LinkUnitFilesContext same as LinkUnitFiles with context
|
||||
func (c *Conn) LinkUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) {
|
||||
result := make([][]interface{}, 0)
|
||||
err := c.sysobj.Call("org.freedesktop.systemd1.Manager.LinkUnitFiles", 0, files, runtime, force).Store(&result)
|
||||
err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.LinkUnitFiles", 0, files, runtime, force).Store(&result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -425,11 +599,17 @@ func (c *Conn) LinkUnitFiles(files []string, runtime bool, force bool) ([]LinkUn
|
||||
// structures with three strings: the type of the change (one of symlink
|
||||
// or unlink), the file name of the symlink and the destination of the
|
||||
// symlink.
|
||||
// Deprecated: use EnableUnitFilesContext instead
|
||||
func (c *Conn) EnableUnitFiles(files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) {
|
||||
return c.EnableUnitFilesContext(context.Background(), files, runtime, force)
|
||||
}
|
||||
|
||||
// EnableUnitFilesContext same as EnableUnitFiles with context
|
||||
func (c *Conn) EnableUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) {
|
||||
var carries_install_info bool
|
||||
|
||||
result := make([][]interface{}, 0)
|
||||
err := c.sysobj.Call("org.freedesktop.systemd1.Manager.EnableUnitFiles", 0, files, runtime, force).Store(&carries_install_info, &result)
|
||||
err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.EnableUnitFiles", 0, files, runtime, force).Store(&carries_install_info, &result)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
@ -471,9 +651,15 @@ type EnableUnitFileChange struct {
|
||||
// consists of structures with three strings: the type of the change (one of
|
||||
// symlink or unlink), the file name of the symlink and the destination of the
|
||||
// symlink.
|
||||
// Deprecated: use DisableUnitFilesContext instead
|
||||
func (c *Conn) DisableUnitFiles(files []string, runtime bool) ([]DisableUnitFileChange, error) {
|
||||
return c.DisableUnitFilesContext(context.Background(), files, runtime)
|
||||
}
|
||||
|
||||
// DisableUnitFilesContext same as DisableUnitFiles with context
|
||||
func (c *Conn) DisableUnitFilesContext(ctx context.Context, files []string, runtime bool) ([]DisableUnitFileChange, error) {
|
||||
result := make([][]interface{}, 0)
|
||||
err := c.sysobj.Call("org.freedesktop.systemd1.Manager.DisableUnitFiles", 0, files, runtime).Store(&result)
|
||||
err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.DisableUnitFiles", 0, files, runtime).Store(&result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -512,9 +698,15 @@ type DisableUnitFileChange struct {
|
||||
// * runtime to specify whether the unit was enabled for runtime
|
||||
// only (true, /run/systemd/..), or persistently (false, /etc/systemd/..)
|
||||
// * force flag
|
||||
// Deprecated: use MaskUnitFilesContext instead
|
||||
func (c *Conn) MaskUnitFiles(files []string, runtime bool, force bool) ([]MaskUnitFileChange, error) {
|
||||
return c.MaskUnitFilesContext(context.Background(), files, runtime, force)
|
||||
}
|
||||
|
||||
// MaskUnitFilesContext same as MaskUnitFiles with context
|
||||
func (c *Conn) MaskUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) ([]MaskUnitFileChange, error) {
|
||||
result := make([][]interface{}, 0)
|
||||
err := c.sysobj.Call("org.freedesktop.systemd1.Manager.MaskUnitFiles", 0, files, runtime, force).Store(&result)
|
||||
err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.MaskUnitFiles", 0, files, runtime, force).Store(&result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -552,9 +744,15 @@ type MaskUnitFileChange struct {
|
||||
// the usual unit search paths)
|
||||
// * runtime to specify whether the unit was enabled for runtime
|
||||
// only (true, /run/systemd/..), or persistently (false, /etc/systemd/..)
|
||||
// Deprecated: use UnmaskUnitFilesContext instead
|
||||
func (c *Conn) UnmaskUnitFiles(files []string, runtime bool) ([]UnmaskUnitFileChange, error) {
|
||||
return c.UnmaskUnitFilesContext(context.Background(), files, runtime)
|
||||
}
|
||||
|
||||
// UnmaskUnitFilesContext same as UnmaskUnitFiles with context
|
||||
func (c *Conn) UnmaskUnitFilesContext(ctx context.Context, files []string, runtime bool) ([]UnmaskUnitFileChange, error) {
|
||||
result := make([][]interface{}, 0)
|
||||
err := c.sysobj.Call("org.freedesktop.systemd1.Manager.UnmaskUnitFiles", 0, files, runtime).Store(&result)
|
||||
err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.UnmaskUnitFiles", 0, files, runtime).Store(&result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -586,8 +784,14 @@ type UnmaskUnitFileChange struct {
|
||||
|
||||
// Reload instructs systemd to scan for and reload unit files. This is
|
||||
// equivalent to a 'systemctl daemon-reload'.
|
||||
// Deprecated: use ReloadContext instead
|
||||
func (c *Conn) Reload() error {
|
||||
return c.sysobj.Call("org.freedesktop.systemd1.Manager.Reload", 0).Store()
|
||||
return c.ReloadContext(context.Background())
|
||||
}
|
||||
|
||||
// ReloadContext same as Reload with context
|
||||
func (c *Conn) ReloadContext(ctx context.Context) error {
|
||||
return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.Reload", 0).Store()
|
||||
}
|
||||
|
||||
func unitPath(name string) dbus.ObjectPath {
|
||||
@ -598,3 +802,48 @@ func unitPath(name string) dbus.ObjectPath {
|
||||
func unitName(dpath dbus.ObjectPath) string {
|
||||
return pathBusUnescape(path.Base(string(dpath)))
|
||||
}
|
||||
|
||||
// Currently queued job definition
|
||||
type JobStatus struct {
|
||||
Id uint32 // The numeric job id
|
||||
Unit string // The primary unit name for this job
|
||||
JobType string // The job type as string
|
||||
Status string // The job state as string
|
||||
JobPath dbus.ObjectPath // The job object path
|
||||
UnitPath dbus.ObjectPath // The unit object path
|
||||
}
|
||||
|
||||
// ListJobs returns an array with all currently queued jobs
|
||||
// Deprecated: use ListJobsContext instead
|
||||
func (c *Conn) ListJobs() ([]JobStatus, error) {
|
||||
return c.ListJobsContext(context.Background())
|
||||
}
|
||||
|
||||
// ListJobsContext same as ListJobs with context
|
||||
func (c *Conn) ListJobsContext(ctx context.Context) ([]JobStatus, error) {
|
||||
return c.listJobsInternal(ctx)
|
||||
}
|
||||
|
||||
func (c *Conn) listJobsInternal(ctx context.Context) ([]JobStatus, error) {
|
||||
result := make([][]interface{}, 0)
|
||||
if err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListJobs", 0).Store(&result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resultInterface := make([]interface{}, len(result))
|
||||
for i := range result {
|
||||
resultInterface[i] = result[i]
|
||||
}
|
||||
|
||||
status := make([]JobStatus, len(result))
|
||||
statusInterface := make([]interface{}, len(status))
|
||||
for i := range status {
|
||||
statusInterface[i] = &status[i]
|
||||
}
|
||||
|
||||
if err := dbus.Store(resultInterface, statusInterface...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return status, nil
|
||||
}
|
||||
|
50
vendor/github.com/godbus/dbus/v5/.travis.yml
generated
vendored
50
vendor/github.com/godbus/dbus/v5/.travis.yml
generated
vendored
@ -1,50 +0,0 @@
|
||||
dist: bionic
|
||||
language: go
|
||||
go_import_path: github.com/godbus/dbus
|
||||
|
||||
go:
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- 1.13.x
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- go: tip
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- dbus
|
||||
- dbus-x11
|
||||
|
||||
before_install:
|
||||
- export GO111MODULE=on
|
||||
|
||||
script:
|
||||
- go test -v -race -mod=readonly ./... # Run all the tests with the race detector enabled
|
||||
- go vet ./... # go vet is the official Go static analyzer
|
||||
|
||||
jobs:
|
||||
include:
|
||||
# The build matrix doesn't cover build stages, so manually expand
|
||||
# the jobs with anchors
|
||||
- &multiarch
|
||||
stage: "Multiarch Test"
|
||||
go: 1.11.x
|
||||
env: TARGETS="386 arm arm64 ppc64le"
|
||||
before_install:
|
||||
- docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
||||
script:
|
||||
- |
|
||||
set -e
|
||||
for target in $TARGETS; do
|
||||
printf "\e[1mRunning test suite under ${target}.\e[0m\n"
|
||||
GOARCH="$target" go test -v ./...
|
||||
printf "\n\n"
|
||||
done
|
||||
- <<: *multiarch
|
||||
go: 1.12.x
|
||||
- <<: *multiarch
|
||||
go: 1.13.x
|
4
vendor/github.com/godbus/dbus/v5/README.markdown
generated
vendored
4
vendor/github.com/godbus/dbus/v5/README.markdown
generated
vendored
@ -1,4 +1,4 @@
|
||||
[](https://travis-ci.org/godbus/dbus)
|
||||

|
||||
|
||||
dbus
|
||||
----
|
||||
@ -32,6 +32,8 @@ gives a short overview over the basic usage.
|
||||
#### Projects using godbus
|
||||
- [notify](https://github.com/esiqveland/notify) provides desktop notifications over dbus into a library.
|
||||
- [go-bluetooth](https://github.com/muka/go-bluetooth) provides a bluetooth client over bluez dbus API.
|
||||
- [playerbm](https://github.com/altdesktop/playerbm) a bookmark utility for media players.
|
||||
- [iwd](https://github.com/shibumi/iwd) go bindings for the internet wireless daemon "iwd".
|
||||
|
||||
Please note that the API is considered unstable for now and may change without
|
||||
further notice.
|
||||
|
2
vendor/github.com/godbus/dbus/v5/auth.go
generated
vendored
2
vendor/github.com/godbus/dbus/v5/auth.go
generated
vendored
@ -37,7 +37,7 @@ const (
|
||||
|
||||
// Auth defines the behaviour of an authentication mechanism.
|
||||
type Auth interface {
|
||||
// Return the name of the mechnism, the argument to the first AUTH command
|
||||
// Return the name of the mechanism, the argument to the first AUTH command
|
||||
// and the next status.
|
||||
FirstData() (name, resp []byte, status AuthStatus)
|
||||
|
||||
|
9
vendor/github.com/godbus/dbus/v5/call.go
generated
vendored
9
vendor/github.com/godbus/dbus/v5/call.go
generated
vendored
@ -24,6 +24,15 @@ type Call struct {
|
||||
// Holds the response once the call is done.
|
||||
Body []interface{}
|
||||
|
||||
// ResponseSequence stores the sequence number of the DBus message containing
|
||||
// the call response (or error). This can be compared to the sequence number
|
||||
// of other call responses and signals on this connection to determine their
|
||||
// relative ordering on the underlying DBus connection.
|
||||
// For errors, ResponseSequence is populated only if the error came from a
|
||||
// DBusMessage that was received or if there was an error receiving. In case of
|
||||
// failure to make the call, ResponseSequence will be NoSequence.
|
||||
ResponseSequence Sequence
|
||||
|
||||
// tracks context and canceler
|
||||
ctx context.Context
|
||||
ctxCanceler context.CancelFunc
|
||||
|
159
vendor/github.com/godbus/dbus/v5/conn.go
generated
vendored
159
vendor/github.com/godbus/dbus/v5/conn.go
generated
vendored
@ -45,6 +45,7 @@ type Conn struct {
|
||||
serialGen SerialGenerator
|
||||
inInt Interceptor
|
||||
outInt Interceptor
|
||||
auth []Auth
|
||||
|
||||
names *nameTracker
|
||||
calls *callTracker
|
||||
@ -59,7 +60,8 @@ type Conn struct {
|
||||
func SessionBus() (conn *Conn, err error) {
|
||||
sessionBusLck.Lock()
|
||||
defer sessionBusLck.Unlock()
|
||||
if sessionBus != nil {
|
||||
if sessionBus != nil &&
|
||||
sessionBus.Connected() {
|
||||
return sessionBus, nil
|
||||
}
|
||||
defer func() {
|
||||
@ -67,19 +69,7 @@ func SessionBus() (conn *Conn, err error) {
|
||||
sessionBus = conn
|
||||
}
|
||||
}()
|
||||
conn, err = SessionBusPrivate()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err = conn.Auth(nil); err != nil {
|
||||
conn.Close()
|
||||
conn = nil
|
||||
return
|
||||
}
|
||||
if err = conn.Hello(); err != nil {
|
||||
conn.Close()
|
||||
conn = nil
|
||||
}
|
||||
conn, err = ConnectSessionBus()
|
||||
return
|
||||
}
|
||||
|
||||
@ -116,7 +106,8 @@ func SessionBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Co
|
||||
func SystemBus() (conn *Conn, err error) {
|
||||
systemBusLck.Lock()
|
||||
defer systemBusLck.Unlock()
|
||||
if systemBus != nil {
|
||||
if systemBus != nil &&
|
||||
systemBus.Connected() {
|
||||
return systemBus, nil
|
||||
}
|
||||
defer func() {
|
||||
@ -124,20 +115,42 @@ func SystemBus() (conn *Conn, err error) {
|
||||
systemBus = conn
|
||||
}
|
||||
}()
|
||||
conn, err = SystemBusPrivate()
|
||||
conn, err = ConnectSystemBus()
|
||||
return
|
||||
}
|
||||
|
||||
// ConnectSessionBus connects to the session bus.
|
||||
func ConnectSessionBus(opts ...ConnOption) (*Conn, error) {
|
||||
address, err := getSessionBusAddress()
|
||||
if err != nil {
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
if err = conn.Auth(nil); err != nil {
|
||||
conn.Close()
|
||||
conn = nil
|
||||
return
|
||||
return Connect(address, opts...)
|
||||
}
|
||||
|
||||
// ConnectSystemBus connects to the system bus.
|
||||
func ConnectSystemBus(opts ...ConnOption) (*Conn, error) {
|
||||
return Connect(getSystemBusPlatformAddress(), opts...)
|
||||
}
|
||||
|
||||
// Connect connects to the given address.
|
||||
//
|
||||
// Returned connection is ready to use and doesn't require calling
|
||||
// Auth and Hello methods to make it usable.
|
||||
func Connect(address string, opts ...ConnOption) (*Conn, error) {
|
||||
conn, err := Dial(address, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = conn.Auth(conn.auth); err != nil {
|
||||
_ = conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
if err = conn.Hello(); err != nil {
|
||||
conn.Close()
|
||||
conn = nil
|
||||
_ = conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// SystemBusPrivate returns a new private connection to the system bus.
|
||||
@ -197,6 +210,14 @@ func WithSerialGenerator(gen SerialGenerator) ConnOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithAuth sets authentication methods for the auth conversation.
|
||||
func WithAuth(methods ...Auth) ConnOption {
|
||||
return func(conn *Conn) error {
|
||||
conn.auth = methods
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Interceptor intercepts incoming and outgoing messages.
|
||||
type Interceptor func(msg *Message)
|
||||
|
||||
@ -309,6 +330,11 @@ func (conn *Conn) Context() context.Context {
|
||||
return conn.ctx
|
||||
}
|
||||
|
||||
// Connected returns whether conn is connected
|
||||
func (conn *Conn) Connected() bool {
|
||||
return conn.ctx.Err() == nil
|
||||
}
|
||||
|
||||
// Eavesdrop causes conn to send all incoming messages to the given channel
|
||||
// without further processing. Method replies, errors and signals will not be
|
||||
// sent to the appropriate channels and method calls will not be handled. If nil
|
||||
@ -342,8 +368,9 @@ func (conn *Conn) Hello() error {
|
||||
}
|
||||
|
||||
// inWorker runs in an own goroutine, reading incoming messages from the
|
||||
// transport and dispatching them appropiately.
|
||||
// transport and dispatching them appropriately.
|
||||
func (conn *Conn) inWorker() {
|
||||
sequenceGen := newSequenceGenerator()
|
||||
for {
|
||||
msg, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
@ -352,7 +379,7 @@ func (conn *Conn) inWorker() {
|
||||
// anything but to shut down all stuff and returns errors to all
|
||||
// pending replies.
|
||||
conn.Close()
|
||||
conn.calls.finalizeAllWithError(err)
|
||||
conn.calls.finalizeAllWithError(sequenceGen, err)
|
||||
return
|
||||
}
|
||||
// invalid messages are ignored
|
||||
@ -381,13 +408,14 @@ func (conn *Conn) inWorker() {
|
||||
if conn.inInt != nil {
|
||||
conn.inInt(msg)
|
||||
}
|
||||
sequence := sequenceGen.next()
|
||||
switch msg.Type {
|
||||
case TypeError:
|
||||
conn.serialGen.RetireSerial(conn.calls.handleDBusError(msg))
|
||||
conn.serialGen.RetireSerial(conn.calls.handleDBusError(sequence, msg))
|
||||
case TypeMethodReply:
|
||||
conn.serialGen.RetireSerial(conn.calls.handleReply(msg))
|
||||
conn.serialGen.RetireSerial(conn.calls.handleReply(sequence, msg))
|
||||
case TypeSignal:
|
||||
conn.handleSignal(msg)
|
||||
conn.handleSignal(sequence, msg)
|
||||
case TypeMethodCall:
|
||||
go conn.handleCall(msg)
|
||||
}
|
||||
@ -395,7 +423,7 @@ func (conn *Conn) inWorker() {
|
||||
}
|
||||
}
|
||||
|
||||
func (conn *Conn) handleSignal(msg *Message) {
|
||||
func (conn *Conn) handleSignal(sequence Sequence, msg *Message) {
|
||||
iface := msg.Headers[FieldInterface].value.(string)
|
||||
member := msg.Headers[FieldMember].value.(string)
|
||||
// as per http://dbus.freedesktop.org/doc/dbus-specification.html ,
|
||||
@ -421,10 +449,11 @@ func (conn *Conn) handleSignal(msg *Message) {
|
||||
}
|
||||
}
|
||||
signal := &Signal{
|
||||
Sender: sender,
|
||||
Path: msg.Headers[FieldPath].value.(ObjectPath),
|
||||
Name: iface + "." + member,
|
||||
Body: msg.Body,
|
||||
Sender: sender,
|
||||
Path: msg.Headers[FieldPath].value.(ObjectPath),
|
||||
Name: iface + "." + member,
|
||||
Body: msg.Body,
|
||||
Sequence: sequence,
|
||||
}
|
||||
conn.signalHandler.DeliverSignal(iface, member, signal)
|
||||
}
|
||||
@ -442,6 +471,9 @@ func (conn *Conn) Object(dest string, path ObjectPath) BusObject {
|
||||
}
|
||||
|
||||
func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) {
|
||||
if msg.serial == 0 {
|
||||
msg.serial = conn.getSerial()
|
||||
}
|
||||
if conn.outInt != nil {
|
||||
conn.outInt(msg)
|
||||
}
|
||||
@ -473,16 +505,16 @@ func (conn *Conn) send(ctx context.Context, msg *Message, ch chan *Call) *Call {
|
||||
if ctx == nil {
|
||||
panic("nil context")
|
||||
}
|
||||
if ch == nil {
|
||||
ch = make(chan *Call, 1)
|
||||
} else if cap(ch) == 0 {
|
||||
panic("dbus: unbuffered channel passed to (*Conn).Send")
|
||||
}
|
||||
|
||||
var call *Call
|
||||
ctx, canceler := context.WithCancel(ctx)
|
||||
msg.serial = conn.getSerial()
|
||||
if msg.Type == TypeMethodCall && msg.Flags&FlagNoReplyExpected == 0 {
|
||||
if ch == nil {
|
||||
ch = make(chan *Call, 5)
|
||||
} else if cap(ch) == 0 {
|
||||
panic("dbus: unbuffered channel passed to (*Conn).Send")
|
||||
}
|
||||
call = new(Call)
|
||||
call.Destination, _ = msg.Headers[FieldDestination].value.(string)
|
||||
call.Path, _ = msg.Headers[FieldPath].value.(ObjectPath)
|
||||
@ -504,7 +536,8 @@ func (conn *Conn) send(ctx context.Context, msg *Message, ch chan *Call) *Call {
|
||||
})
|
||||
} else {
|
||||
canceler()
|
||||
call = &Call{Err: nil}
|
||||
call = &Call{Err: nil, Done: ch}
|
||||
ch <- call
|
||||
conn.sendMessageAndIfClosed(msg, func() {
|
||||
call = &Call{Err: ErrClosed}
|
||||
})
|
||||
@ -529,7 +562,6 @@ func (conn *Conn) sendError(err error, dest string, serial uint32) {
|
||||
}
|
||||
msg := new(Message)
|
||||
msg.Type = TypeError
|
||||
msg.serial = conn.getSerial()
|
||||
msg.Headers = make(map[HeaderField]Variant)
|
||||
if dest != "" {
|
||||
msg.Headers[FieldDestination] = MakeVariant(dest)
|
||||
@ -548,7 +580,6 @@ func (conn *Conn) sendError(err error, dest string, serial uint32) {
|
||||
func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) {
|
||||
msg := new(Message)
|
||||
msg.Type = TypeMethodReply
|
||||
msg.serial = conn.getSerial()
|
||||
msg.Headers = make(map[HeaderField]Variant)
|
||||
if dest != "" {
|
||||
msg.Headers[FieldDestination] = MakeVariant(dest)
|
||||
@ -564,8 +595,14 @@ func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) {
|
||||
// AddMatchSignal registers the given match rule to receive broadcast
|
||||
// signals based on their contents.
|
||||
func (conn *Conn) AddMatchSignal(options ...MatchOption) error {
|
||||
return conn.AddMatchSignalContext(context.Background(), options...)
|
||||
}
|
||||
|
||||
// AddMatchSignalContext acts like AddMatchSignal but takes a context.
|
||||
func (conn *Conn) AddMatchSignalContext(ctx context.Context, options ...MatchOption) error {
|
||||
options = append([]MatchOption{withMatchType("signal")}, options...)
|
||||
return conn.busObj.Call(
|
||||
return conn.busObj.CallWithContext(
|
||||
ctx,
|
||||
"org.freedesktop.DBus.AddMatch", 0,
|
||||
formatMatchOptions(options),
|
||||
).Store()
|
||||
@ -573,8 +610,14 @@ func (conn *Conn) AddMatchSignal(options ...MatchOption) error {
|
||||
|
||||
// RemoveMatchSignal removes the first rule that matches previously registered with AddMatchSignal.
|
||||
func (conn *Conn) RemoveMatchSignal(options ...MatchOption) error {
|
||||
return conn.RemoveMatchSignalContext(context.Background(), options...)
|
||||
}
|
||||
|
||||
// RemoveMatchSignalContext acts like RemoveMatchSignal but takes a context.
|
||||
func (conn *Conn) RemoveMatchSignalContext(ctx context.Context, options ...MatchOption) error {
|
||||
options = append([]MatchOption{withMatchType("signal")}, options...)
|
||||
return conn.busObj.Call(
|
||||
return conn.busObj.CallWithContext(
|
||||
ctx,
|
||||
"org.freedesktop.DBus.RemoveMatch", 0,
|
||||
formatMatchOptions(options),
|
||||
).Store()
|
||||
@ -639,10 +682,11 @@ func (e Error) Error() string {
|
||||
// Signal represents a D-Bus message of type Signal. The name member is given in
|
||||
// "interface.member" notation, e.g. org.freedesktop.D-Bus.NameLost.
|
||||
type Signal struct {
|
||||
Sender string
|
||||
Path ObjectPath
|
||||
Name string
|
||||
Body []interface{}
|
||||
Sender string
|
||||
Path ObjectPath
|
||||
Name string
|
||||
Body []interface{}
|
||||
Sequence Sequence
|
||||
}
|
||||
|
||||
// transport is a D-Bus transport.
|
||||
@ -825,25 +869,25 @@ func (tracker *callTracker) track(sn uint32, call *Call) {
|
||||
tracker.lck.Unlock()
|
||||
}
|
||||
|
||||
func (tracker *callTracker) handleReply(msg *Message) uint32 {
|
||||
func (tracker *callTracker) handleReply(sequence Sequence, msg *Message) uint32 {
|
||||
serial := msg.Headers[FieldReplySerial].value.(uint32)
|
||||
tracker.lck.RLock()
|
||||
_, ok := tracker.calls[serial]
|
||||
tracker.lck.RUnlock()
|
||||
if ok {
|
||||
tracker.finalizeWithBody(serial, msg.Body)
|
||||
tracker.finalizeWithBody(serial, sequence, msg.Body)
|
||||
}
|
||||
return serial
|
||||
}
|
||||
|
||||
func (tracker *callTracker) handleDBusError(msg *Message) uint32 {
|
||||
func (tracker *callTracker) handleDBusError(sequence Sequence, msg *Message) uint32 {
|
||||
serial := msg.Headers[FieldReplySerial].value.(uint32)
|
||||
tracker.lck.RLock()
|
||||
_, ok := tracker.calls[serial]
|
||||
tracker.lck.RUnlock()
|
||||
if ok {
|
||||
name, _ := msg.Headers[FieldErrorName].value.(string)
|
||||
tracker.finalizeWithError(serial, Error{name, msg.Body})
|
||||
tracker.finalizeWithError(serial, sequence, Error{name, msg.Body})
|
||||
}
|
||||
return serial
|
||||
}
|
||||
@ -856,7 +900,7 @@ func (tracker *callTracker) handleSendError(msg *Message, err error) {
|
||||
_, ok := tracker.calls[msg.serial]
|
||||
tracker.lck.RUnlock()
|
||||
if ok {
|
||||
tracker.finalizeWithError(msg.serial, err)
|
||||
tracker.finalizeWithError(msg.serial, NoSequence, err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -871,7 +915,7 @@ func (tracker *callTracker) finalize(sn uint32) {
|
||||
}
|
||||
}
|
||||
|
||||
func (tracker *callTracker) finalizeWithBody(sn uint32, body []interface{}) {
|
||||
func (tracker *callTracker) finalizeWithBody(sn uint32, sequence Sequence, body []interface{}) {
|
||||
tracker.lck.Lock()
|
||||
c, ok := tracker.calls[sn]
|
||||
if ok {
|
||||
@ -880,11 +924,12 @@ func (tracker *callTracker) finalizeWithBody(sn uint32, body []interface{}) {
|
||||
tracker.lck.Unlock()
|
||||
if ok {
|
||||
c.Body = body
|
||||
c.ResponseSequence = sequence
|
||||
c.done()
|
||||
}
|
||||
}
|
||||
|
||||
func (tracker *callTracker) finalizeWithError(sn uint32, err error) {
|
||||
func (tracker *callTracker) finalizeWithError(sn uint32, sequence Sequence, err error) {
|
||||
tracker.lck.Lock()
|
||||
c, ok := tracker.calls[sn]
|
||||
if ok {
|
||||
@ -893,11 +938,12 @@ func (tracker *callTracker) finalizeWithError(sn uint32, err error) {
|
||||
tracker.lck.Unlock()
|
||||
if ok {
|
||||
c.Err = err
|
||||
c.ResponseSequence = sequence
|
||||
c.done()
|
||||
}
|
||||
}
|
||||
|
||||
func (tracker *callTracker) finalizeAllWithError(err error) {
|
||||
func (tracker *callTracker) finalizeAllWithError(sequenceGen *sequenceGenerator, err error) {
|
||||
tracker.lck.Lock()
|
||||
closedCalls := make([]*Call, 0, len(tracker.calls))
|
||||
for sn := range tracker.calls {
|
||||
@ -907,6 +953,7 @@ func (tracker *callTracker) finalizeAllWithError(err error) {
|
||||
tracker.lck.Unlock()
|
||||
for _, call := range closedCalls {
|
||||
call.Err = err
|
||||
call.ResponseSequence = sequenceGen.next()
|
||||
call.done()
|
||||
}
|
||||
}
|
||||
|
4
vendor/github.com/godbus/dbus/v5/dbus.go
generated
vendored
4
vendor/github.com/godbus/dbus/v5/dbus.go
generated
vendored
@ -28,6 +28,7 @@ var (
|
||||
interfaceType = reflect.TypeOf((*interface{})(nil)).Elem()
|
||||
unixFDType = reflect.TypeOf(UnixFD(0))
|
||||
unixFDIndexType = reflect.TypeOf(UnixFDIndex(0))
|
||||
errType = reflect.TypeOf((*error)(nil)).Elem()
|
||||
)
|
||||
|
||||
// An InvalidTypeError signals that a value which cannot be represented in the
|
||||
@ -63,6 +64,9 @@ func storeInterfaces(src, dest interface{}) error {
|
||||
|
||||
func store(dest, src reflect.Value) error {
|
||||
if dest.Kind() == reflect.Ptr {
|
||||
if dest.IsNil() {
|
||||
dest.Set(reflect.New(dest.Type().Elem()))
|
||||
}
|
||||
return store(dest.Elem(), src)
|
||||
}
|
||||
switch src.Kind() {
|
||||
|
22
vendor/github.com/godbus/dbus/v5/default_handler.go
generated
vendored
22
vendor/github.com/godbus/dbus/v5/default_handler.go
generated
vendored
@ -126,14 +126,28 @@ func (m exportedMethod) Call(args ...interface{}) ([]interface{}, error) {
|
||||
}
|
||||
|
||||
ret := m.Value.Call(params)
|
||||
|
||||
err := ret[t.NumOut()-1].Interface().(*Error)
|
||||
ret = ret[:t.NumOut()-1]
|
||||
var err error
|
||||
nilErr := false // The reflection will find almost-nils, let's only pass back clean ones!
|
||||
if t.NumOut() > 0 {
|
||||
if e, ok := ret[t.NumOut()-1].Interface().(*Error); ok { // godbus *Error
|
||||
nilErr = ret[t.NumOut()-1].IsNil()
|
||||
ret = ret[:t.NumOut()-1]
|
||||
err = e
|
||||
} else if ret[t.NumOut()-1].Type().Implements(errType) { // Go error
|
||||
i := ret[t.NumOut()-1].Interface()
|
||||
if i == nil {
|
||||
nilErr = ret[t.NumOut()-1].IsNil()
|
||||
} else {
|
||||
err = i.(error)
|
||||
}
|
||||
ret = ret[:t.NumOut()-1]
|
||||
}
|
||||
}
|
||||
out := make([]interface{}, len(ret))
|
||||
for i, val := range ret {
|
||||
out[i] = val.Interface()
|
||||
}
|
||||
if err == nil {
|
||||
if nilErr || err == nil {
|
||||
//concrete type to interface nil is a special case
|
||||
return out, nil
|
||||
}
|
||||
|
61
vendor/github.com/godbus/dbus/v5/export.go
generated
vendored
61
vendor/github.com/godbus/dbus/v5/export.go
generated
vendored
@ -69,6 +69,22 @@ func getMethods(in interface{}, mapping map[string]string) map[string]reflect.Va
|
||||
return methods
|
||||
}
|
||||
|
||||
func getAllMethods(in interface{}, mapping map[string]string) map[string]reflect.Value {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
methods := make(map[string]reflect.Value)
|
||||
val := reflect.ValueOf(in)
|
||||
typ := val.Type()
|
||||
for i := 0; i < typ.NumMethod(); i++ {
|
||||
methtype := typ.Method(i)
|
||||
method := val.Method(i)
|
||||
// map names while building table
|
||||
methods[computeMethodName(methtype.Name, mapping)] = method
|
||||
}
|
||||
return methods
|
||||
}
|
||||
|
||||
func standardMethodArgumentDecode(m Method, sender string, msg *Message, body []interface{}) ([]interface{}, error) {
|
||||
pointers := make([]interface{}, m.NumArguments())
|
||||
decode := make([]interface{}, 0, len(body))
|
||||
@ -159,7 +175,6 @@ func (conn *Conn) handleCall(msg *Message) {
|
||||
if msg.Flags&FlagNoReplyExpected == 0 {
|
||||
reply := new(Message)
|
||||
reply.Type = TypeMethodReply
|
||||
reply.serial = conn.getSerial()
|
||||
reply.Headers = make(map[HeaderField]Variant)
|
||||
if hasSender {
|
||||
reply.Headers[FieldDestination] = msg.Headers[FieldSender]
|
||||
@ -195,7 +210,6 @@ func (conn *Conn) Emit(path ObjectPath, name string, values ...interface{}) erro
|
||||
}
|
||||
msg := new(Message)
|
||||
msg.Type = TypeSignal
|
||||
msg.serial = conn.getSerial()
|
||||
msg.Headers = make(map[HeaderField]Variant)
|
||||
msg.Headers[FieldInterface] = MakeVariant(iface)
|
||||
msg.Headers[FieldMember] = MakeVariant(member)
|
||||
@ -247,6 +261,18 @@ func (conn *Conn) Export(v interface{}, path ObjectPath, iface string) error {
|
||||
return conn.ExportWithMap(v, nil, path, iface)
|
||||
}
|
||||
|
||||
// ExportAll registers all exported methods defined by the given object on
|
||||
// the message bus.
|
||||
//
|
||||
// Unlike Export there is no requirement to have the last parameter as type
|
||||
// *Error. If you want to be able to return error then you can append an error
|
||||
// type parameter to your method signature. If the error returned is not nil,
|
||||
// it is sent back to the caller as an error. Otherwise, a method reply is
|
||||
// sent with the other return values as its body.
|
||||
func (conn *Conn) ExportAll(v interface{}, path ObjectPath, iface string) error {
|
||||
return conn.export(getAllMethods(v, nil), path, iface, false)
|
||||
}
|
||||
|
||||
// ExportWithMap works exactly like Export but provides the ability to remap
|
||||
// method names (e.g. export a lower-case method).
|
||||
//
|
||||
@ -299,19 +325,22 @@ func (conn *Conn) ExportSubtreeMethodTable(methods map[string]interface{}, path
|
||||
}
|
||||
|
||||
func (conn *Conn) exportMethodTable(methods map[string]interface{}, path ObjectPath, iface string, includeSubtree bool) error {
|
||||
out := make(map[string]reflect.Value)
|
||||
for name, method := range methods {
|
||||
rval := reflect.ValueOf(method)
|
||||
if rval.Kind() != reflect.Func {
|
||||
continue
|
||||
var out map[string]reflect.Value
|
||||
if methods != nil {
|
||||
out = make(map[string]reflect.Value)
|
||||
for name, method := range methods {
|
||||
rval := reflect.ValueOf(method)
|
||||
if rval.Kind() != reflect.Func {
|
||||
continue
|
||||
}
|
||||
t := rval.Type()
|
||||
// only track valid methods must return *Error as last arg
|
||||
if t.NumOut() == 0 ||
|
||||
t.Out(t.NumOut()-1) != reflect.TypeOf(&ErrMsgInvalidArg) {
|
||||
continue
|
||||
}
|
||||
out[name] = rval
|
||||
}
|
||||
t := rval.Type()
|
||||
// only track valid methods must return *Error as last arg
|
||||
if t.NumOut() == 0 ||
|
||||
t.Out(t.NumOut()-1) != reflect.TypeOf(&ErrMsgInvalidArg) {
|
||||
continue
|
||||
}
|
||||
out[name] = rval
|
||||
}
|
||||
return conn.export(out, path, iface, includeSubtree)
|
||||
}
|
||||
@ -327,12 +356,12 @@ func (conn *Conn) unexport(h *defaultHandler, path ObjectPath, iface string) err
|
||||
return nil
|
||||
}
|
||||
|
||||
// exportWithMap is the worker function for all exports/registrations.
|
||||
// export is the worker function for all exports/registrations.
|
||||
func (conn *Conn) export(methods map[string]reflect.Value, path ObjectPath, iface string, includeSubtree bool) error {
|
||||
h, ok := conn.handler.(*defaultHandler)
|
||||
if !ok {
|
||||
return fmt.Errorf(
|
||||
`dbus: export only allowed on the default hander handler have %T"`,
|
||||
`dbus: export only allowed on the default handler. Received: %T"`,
|
||||
conn.handler)
|
||||
}
|
||||
|
||||
|
27
vendor/github.com/godbus/dbus/v5/match.go
generated
vendored
27
vendor/github.com/godbus/dbus/v5/match.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
package dbus
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -60,3 +61,29 @@ func WithMatchPathNamespace(namespace ObjectPath) MatchOption {
|
||||
func WithMatchDestination(destination string) MatchOption {
|
||||
return WithMatchOption("destination", destination)
|
||||
}
|
||||
|
||||
// WithMatchArg sets argN match option, range of N is 0 to 63.
|
||||
func WithMatchArg(argIdx int, value string) MatchOption {
|
||||
if argIdx < 0 || argIdx > 63 {
|
||||
panic("range of argument index is 0 to 63")
|
||||
}
|
||||
return WithMatchOption("arg"+strconv.Itoa(argIdx), value)
|
||||
}
|
||||
|
||||
// WithMatchArgPath sets argN path match option, range of N is 0 to 63.
|
||||
func WithMatchArgPath(argIdx int, path string) MatchOption {
|
||||
if argIdx < 0 || argIdx > 63 {
|
||||
panic("range of argument index is 0 to 63")
|
||||
}
|
||||
return WithMatchOption("arg"+strconv.Itoa(argIdx)+"path", path)
|
||||
}
|
||||
|
||||
// WithMatchArg0Namespace sets arg0namespace match option.
|
||||
func WithMatchArg0Namespace(arg0Namespace string) MatchOption {
|
||||
return WithMatchOption("arg0namespace", arg0Namespace)
|
||||
}
|
||||
|
||||
// WithMatchEavesdrop sets eavesdrop match option.
|
||||
func WithMatchEavesdrop(eavesdrop bool) MatchOption {
|
||||
return WithMatchOption("eavesdrop", strconv.FormatBool(eavesdrop))
|
||||
}
|
||||
|
65
vendor/github.com/godbus/dbus/v5/object.go
generated
vendored
65
vendor/github.com/godbus/dbus/v5/object.go
generated
vendored
@ -16,6 +16,7 @@ type BusObject interface {
|
||||
AddMatchSignal(iface, member string, options ...MatchOption) *Call
|
||||
RemoveMatchSignal(iface, member string, options ...MatchOption) *Call
|
||||
GetProperty(p string) (Variant, error)
|
||||
StoreProperty(p string, value interface{}) error
|
||||
SetProperty(p string, v interface{}) error
|
||||
Destination() string
|
||||
Path() ObjectPath
|
||||
@ -109,7 +110,6 @@ func (o *Object) createCall(ctx context.Context, method string, flags Flags, ch
|
||||
method = method[i+1:]
|
||||
msg := new(Message)
|
||||
msg.Type = TypeMethodCall
|
||||
msg.serial = o.conn.getSerial()
|
||||
msg.Flags = flags & (FlagNoAutoStart | FlagNoReplyExpected)
|
||||
msg.Headers = make(map[HeaderField]Variant)
|
||||
msg.Headers[FieldPath] = MakeVariant(o.path)
|
||||
@ -122,68 +122,31 @@ func (o *Object) createCall(ctx context.Context, method string, flags Flags, ch
|
||||
if len(args) > 0 {
|
||||
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(args...))
|
||||
}
|
||||
if msg.Flags&FlagNoReplyExpected == 0 {
|
||||
if ch == nil {
|
||||
ch = make(chan *Call, 1)
|
||||
} else if cap(ch) == 0 {
|
||||
panic("dbus: unbuffered channel passed to (*Object).Go")
|
||||
}
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
call := &Call{
|
||||
Destination: o.dest,
|
||||
Path: o.path,
|
||||
Method: method,
|
||||
Args: args,
|
||||
Done: ch,
|
||||
ctxCanceler: cancel,
|
||||
ctx: ctx,
|
||||
}
|
||||
o.conn.calls.track(msg.serial, call)
|
||||
o.conn.sendMessageAndIfClosed(msg, func() {
|
||||
o.conn.calls.handleSendError(msg, ErrClosed)
|
||||
cancel()
|
||||
})
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
o.conn.calls.handleSendError(msg, ctx.Err())
|
||||
}()
|
||||
|
||||
return call
|
||||
}
|
||||
done := make(chan *Call, 1)
|
||||
call := &Call{
|
||||
Err: nil,
|
||||
Done: done,
|
||||
}
|
||||
defer func() {
|
||||
call.Done <- call
|
||||
close(done)
|
||||
}()
|
||||
o.conn.sendMessageAndIfClosed(msg, func() {
|
||||
call.Err = ErrClosed
|
||||
})
|
||||
return call
|
||||
return o.conn.SendWithContext(ctx, msg, ch)
|
||||
}
|
||||
|
||||
// GetProperty calls org.freedesktop.DBus.Properties.Get on the given
|
||||
// object. The property name must be given in interface.member notation.
|
||||
func (o *Object) GetProperty(p string) (Variant, error) {
|
||||
var result Variant
|
||||
err := o.StoreProperty(p, &result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// StoreProperty calls org.freedesktop.DBus.Properties.Get on the given
|
||||
// object. The property name must be given in interface.member notation.
|
||||
// It stores the returned property into the provided value.
|
||||
func (o *Object) StoreProperty(p string, value interface{}) error {
|
||||
idx := strings.LastIndex(p, ".")
|
||||
if idx == -1 || idx+1 == len(p) {
|
||||
return Variant{}, errors.New("dbus: invalid property " + p)
|
||||
return errors.New("dbus: invalid property " + p)
|
||||
}
|
||||
|
||||
iface := p[:idx]
|
||||
prop := p[idx+1:]
|
||||
|
||||
result := Variant{}
|
||||
err := o.Call("org.freedesktop.DBus.Properties.Get", 0, iface, prop).Store(&result)
|
||||
|
||||
if err != nil {
|
||||
return Variant{}, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
return o.Call("org.freedesktop.DBus.Properties.Get", 0, iface, prop).
|
||||
Store(value)
|
||||
}
|
||||
|
||||
// SetProperty calls org.freedesktop.DBus.Properties.Set on the given
|
||||
|
24
vendor/github.com/godbus/dbus/v5/sequence.go
generated
vendored
Normal file
24
vendor/github.com/godbus/dbus/v5/sequence.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
package dbus
|
||||
|
||||
// Sequence represents the value of a monotonically increasing counter.
|
||||
type Sequence uint64
|
||||
|
||||
const (
|
||||
// NoSequence indicates the absence of a sequence value.
|
||||
NoSequence Sequence = 0
|
||||
)
|
||||
|
||||
// sequenceGenerator represents a monotonically increasing counter.
|
||||
type sequenceGenerator struct {
|
||||
nextSequence Sequence
|
||||
}
|
||||
|
||||
func (generator *sequenceGenerator) next() Sequence {
|
||||
result := generator.nextSequence
|
||||
generator.nextSequence++
|
||||
return result
|
||||
}
|
||||
|
||||
func newSequenceGenerator() *sequenceGenerator {
|
||||
return &sequenceGenerator{nextSequence: 1}
|
||||
}
|
125
vendor/github.com/godbus/dbus/v5/sequential_handler.go
generated
vendored
Normal file
125
vendor/github.com/godbus/dbus/v5/sequential_handler.go
generated
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
package dbus
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// NewSequentialSignalHandler returns an instance of a new
|
||||
// signal handler that guarantees sequential processing of signals. It is a
|
||||
// guarantee of this signal handler that signals will be written to
|
||||
// channels in the order they are received on the DBus connection.
|
||||
func NewSequentialSignalHandler() SignalHandler {
|
||||
return &sequentialSignalHandler{}
|
||||
}
|
||||
|
||||
type sequentialSignalHandler struct {
|
||||
mu sync.RWMutex
|
||||
closed bool
|
||||
signals []*sequentialSignalChannelData
|
||||
}
|
||||
|
||||
func (sh *sequentialSignalHandler) DeliverSignal(intf, name string, signal *Signal) {
|
||||
sh.mu.RLock()
|
||||
defer sh.mu.RUnlock()
|
||||
if sh.closed {
|
||||
return
|
||||
}
|
||||
for _, scd := range sh.signals {
|
||||
scd.deliver(signal)
|
||||
}
|
||||
}
|
||||
|
||||
func (sh *sequentialSignalHandler) Terminate() {
|
||||
sh.mu.Lock()
|
||||
defer sh.mu.Unlock()
|
||||
if sh.closed {
|
||||
return
|
||||
}
|
||||
|
||||
for _, scd := range sh.signals {
|
||||
scd.close()
|
||||
close(scd.ch)
|
||||
}
|
||||
sh.closed = true
|
||||
sh.signals = nil
|
||||
}
|
||||
|
||||
func (sh *sequentialSignalHandler) AddSignal(ch chan<- *Signal) {
|
||||
sh.mu.Lock()
|
||||
defer sh.mu.Unlock()
|
||||
if sh.closed {
|
||||
return
|
||||
}
|
||||
sh.signals = append(sh.signals, newSequentialSignalChannelData(ch))
|
||||
}
|
||||
|
||||
func (sh *sequentialSignalHandler) RemoveSignal(ch chan<- *Signal) {
|
||||
sh.mu.Lock()
|
||||
defer sh.mu.Unlock()
|
||||
if sh.closed {
|
||||
return
|
||||
}
|
||||
for i := len(sh.signals) - 1; i >= 0; i-- {
|
||||
if ch == sh.signals[i].ch {
|
||||
sh.signals[i].close()
|
||||
copy(sh.signals[i:], sh.signals[i+1:])
|
||||
sh.signals[len(sh.signals)-1] = nil
|
||||
sh.signals = sh.signals[:len(sh.signals)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type sequentialSignalChannelData struct {
|
||||
ch chan<- *Signal
|
||||
in chan *Signal
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
func newSequentialSignalChannelData(ch chan<- *Signal) *sequentialSignalChannelData {
|
||||
scd := &sequentialSignalChannelData{
|
||||
ch: ch,
|
||||
in: make(chan *Signal),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
go scd.bufferSignals()
|
||||
return scd
|
||||
}
|
||||
|
||||
func (scd *sequentialSignalChannelData) bufferSignals() {
|
||||
defer close(scd.done)
|
||||
|
||||
// Ensure that signals are delivered to scd.ch in the same
|
||||
// order they are received from scd.in.
|
||||
var queue []*Signal
|
||||
for {
|
||||
if len(queue) == 0 {
|
||||
signal, ok := <- scd.in
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
queue = append(queue, signal)
|
||||
}
|
||||
select {
|
||||
case scd.ch <- queue[0]:
|
||||
copy(queue, queue[1:])
|
||||
queue[len(queue)-1] = nil
|
||||
queue = queue[:len(queue)-1]
|
||||
case signal, ok := <-scd.in:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
queue = append(queue, signal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (scd *sequentialSignalChannelData) deliver(signal *Signal) {
|
||||
scd.in <- signal
|
||||
}
|
||||
|
||||
func (scd *sequentialSignalChannelData) close() {
|
||||
close(scd.in)
|
||||
// Ensure that bufferSignals() has exited and won't attempt
|
||||
// any future sends on scd.ch
|
||||
<-scd.done
|
||||
}
|
2
vendor/github.com/godbus/dbus/v5/sig.go
generated
vendored
2
vendor/github.com/godbus/dbus/v5/sig.go
generated
vendored
@ -137,7 +137,7 @@ func ParseSignatureMust(s string) Signature {
|
||||
return sig
|
||||
}
|
||||
|
||||
// Empty retruns whether the signature is the empty signature.
|
||||
// Empty returns whether the signature is the empty signature.
|
||||
func (s Signature) Empty() bool {
|
||||
return s.str == ""
|
||||
}
|
||||
|
1
vendor/github.com/godbus/dbus/v5/transport_unixcred_freebsd.go
generated
vendored
1
vendor/github.com/godbus/dbus/v5/transport_unixcred_freebsd.go
generated
vendored
@ -10,6 +10,7 @@ package dbus
|
||||
/*
|
||||
const int sizeofPtr = sizeof(void*);
|
||||
#define _WANT_UCRED
|
||||
#include <sys/types.h>
|
||||
#include <sys/ucred.h>
|
||||
*/
|
||||
import "C"
|
||||
|
6
vendor/github.com/godbus/dbus/v5/variant.go
generated
vendored
6
vendor/github.com/godbus/dbus/v5/variant.go
generated
vendored
@ -142,3 +142,9 @@ func (v Variant) String() string {
|
||||
func (v Variant) Value() interface{} {
|
||||
return v.value
|
||||
}
|
||||
|
||||
// Store converts the variant into a native go type using the same
|
||||
// mechanism as the "Store" function.
|
||||
func (v Variant) Store(value interface{}) error {
|
||||
return storeInterfaces(v.value, value)
|
||||
}
|
||||
|
2
vendor/github.com/opencontainers/runc/libcontainer/user/MAINTAINERS
generated
vendored
2
vendor/github.com/opencontainers/runc/libcontainer/user/MAINTAINERS
generated
vendored
@ -1,2 +0,0 @@
|
||||
Tianon Gravi <admwiggin@gmail.com> (@tianon)
|
||||
Aleksa Sarai <cyphar@cyphar.com> (@cyphar)
|
41
vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go
generated
vendored
41
vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go
generated
vendored
@ -1,41 +0,0 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// The current operating system does not provide the required data for user lookups.
|
||||
ErrUnsupported = errors.New("user lookup: operating system does not provide passwd-formatted data")
|
||||
// No matching entries found in file.
|
||||
ErrNoPasswdEntries = errors.New("no matching entries in passwd file")
|
||||
ErrNoGroupEntries = errors.New("no matching entries in group file")
|
||||
)
|
||||
|
||||
// LookupUser looks up a user by their username in /etc/passwd. If the user
|
||||
// cannot be found (or there is no /etc/passwd file on the filesystem), then
|
||||
// LookupUser returns an error.
|
||||
func LookupUser(username string) (User, error) {
|
||||
return lookupUser(username)
|
||||
}
|
||||
|
||||
// LookupUid looks up a user by their user id in /etc/passwd. If the user cannot
|
||||
// be found (or there is no /etc/passwd file on the filesystem), then LookupId
|
||||
// returns an error.
|
||||
func LookupUid(uid int) (User, error) {
|
||||
return lookupUid(uid)
|
||||
}
|
||||
|
||||
// LookupGroup looks up a group by its name in /etc/group. If the group cannot
|
||||
// be found (or there is no /etc/group file on the filesystem), then LookupGroup
|
||||
// returns an error.
|
||||
func LookupGroup(groupname string) (Group, error) {
|
||||
return lookupGroup(groupname)
|
||||
}
|
||||
|
||||
// LookupGid looks up a group by its group id in /etc/group. If the group cannot
|
||||
// be found (or there is no /etc/group file on the filesystem), then LookupGid
|
||||
// returns an error.
|
||||
func LookupGid(gid int) (Group, error) {
|
||||
return lookupGid(gid)
|
||||
}
|
20
vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go
generated
vendored
20
vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go
generated
vendored
@ -16,13 +16,19 @@ const (
|
||||
unixGroupPath = "/etc/group"
|
||||
)
|
||||
|
||||
func lookupUser(username string) (User, error) {
|
||||
// LookupUser looks up a user by their username in /etc/passwd. If the user
|
||||
// cannot be found (or there is no /etc/passwd file on the filesystem), then
|
||||
// LookupUser returns an error.
|
||||
func LookupUser(username string) (User, error) {
|
||||
return lookupUserFunc(func(u User) bool {
|
||||
return u.Name == username
|
||||
})
|
||||
}
|
||||
|
||||
func lookupUid(uid int) (User, error) {
|
||||
// LookupUid looks up a user by their user id in /etc/passwd. If the user cannot
|
||||
// be found (or there is no /etc/passwd file on the filesystem), then LookupId
|
||||
// returns an error.
|
||||
func LookupUid(uid int) (User, error) {
|
||||
return lookupUserFunc(func(u User) bool {
|
||||
return u.Uid == uid
|
||||
})
|
||||
@ -51,13 +57,19 @@ func lookupUserFunc(filter func(u User) bool) (User, error) {
|
||||
return users[0], nil
|
||||
}
|
||||
|
||||
func lookupGroup(groupname string) (Group, error) {
|
||||
// LookupGroup looks up a group by its name in /etc/group. If the group cannot
|
||||
// be found (or there is no /etc/group file on the filesystem), then LookupGroup
|
||||
// returns an error.
|
||||
func LookupGroup(groupname string) (Group, error) {
|
||||
return lookupGroupFunc(func(g Group) bool {
|
||||
return g.Name == groupname
|
||||
})
|
||||
}
|
||||
|
||||
func lookupGid(gid int) (Group, error) {
|
||||
// LookupGid looks up a group by its group id in /etc/group. If the group cannot
|
||||
// be found (or there is no /etc/group file on the filesystem), then LookupGid
|
||||
// returns an error.
|
||||
func LookupGid(gid int) (Group, error) {
|
||||
return lookupGroupFunc(func(g Group) bool {
|
||||
return g.Gid == gid
|
||||
})
|
||||
|
40
vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go
generated
vendored
40
vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go
generated
vendored
@ -1,40 +0,0 @@
|
||||
// +build windows
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"os/user"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func lookupUser(username string) (User, error) {
|
||||
u, err := user.Lookup(username)
|
||||
if err != nil {
|
||||
return User{}, err
|
||||
}
|
||||
return userFromOS(u)
|
||||
}
|
||||
|
||||
func lookupUid(uid int) (User, error) {
|
||||
u, err := user.LookupId(strconv.Itoa(uid))
|
||||
if err != nil {
|
||||
return User{}, err
|
||||
}
|
||||
return userFromOS(u)
|
||||
}
|
||||
|
||||
func lookupGroup(groupname string) (Group, error) {
|
||||
g, err := user.LookupGroup(groupname)
|
||||
if err != nil {
|
||||
return Group{}, err
|
||||
}
|
||||
return groupFromOS(g)
|
||||
}
|
||||
|
||||
func lookupGid(gid int) (Group, error) {
|
||||
g, err := user.LookupGroupId(strconv.Itoa(gid))
|
||||
if err != nil {
|
||||
return Group{}, err
|
||||
}
|
||||
return groupFromOS(g)
|
||||
}
|
48
vendor/github.com/opencontainers/runc/libcontainer/user/user.go
generated
vendored
48
vendor/github.com/opencontainers/runc/libcontainer/user/user.go
generated
vendored
@ -2,10 +2,10 @@ package user
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/user"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
@ -16,6 +16,13 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
// The current operating system does not provide the required data for user lookups.
|
||||
ErrUnsupported = errors.New("user lookup: operating system does not provide passwd-formatted data")
|
||||
|
||||
// No matching entries found in file.
|
||||
ErrNoPasswdEntries = errors.New("no matching entries in passwd file")
|
||||
ErrNoGroupEntries = errors.New("no matching entries in group file")
|
||||
|
||||
ErrRange = fmt.Errorf("uids and gids must be in range %d-%d", minId, maxId)
|
||||
)
|
||||
|
||||
@ -29,28 +36,6 @@ type User struct {
|
||||
Shell string
|
||||
}
|
||||
|
||||
// userFromOS converts an os/user.(*User) to local User
|
||||
//
|
||||
// (This does not include Pass, Shell or Gecos)
|
||||
func userFromOS(u *user.User) (User, error) {
|
||||
newUser := User{
|
||||
Name: u.Username,
|
||||
Home: u.HomeDir,
|
||||
}
|
||||
id, err := strconv.Atoi(u.Uid)
|
||||
if err != nil {
|
||||
return newUser, err
|
||||
}
|
||||
newUser.Uid = id
|
||||
|
||||
id, err = strconv.Atoi(u.Gid)
|
||||
if err != nil {
|
||||
return newUser, err
|
||||
}
|
||||
newUser.Gid = id
|
||||
return newUser, nil
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
Name string
|
||||
Pass string
|
||||
@ -58,23 +43,6 @@ type Group struct {
|
||||
List []string
|
||||
}
|
||||
|
||||
// groupFromOS converts an os/user.(*Group) to local Group
|
||||
//
|
||||
// (This does not include Pass or List)
|
||||
func groupFromOS(g *user.Group) (Group, error) {
|
||||
newGroup := Group{
|
||||
Name: g.Name,
|
||||
}
|
||||
|
||||
id, err := strconv.Atoi(g.Gid)
|
||||
if err != nil {
|
||||
return newGroup, err
|
||||
}
|
||||
newGroup.Gid = id
|
||||
|
||||
return newGroup, nil
|
||||
}
|
||||
|
||||
// SubID represents an entry in /etc/sub{u,g}id
|
||||
type SubID struct {
|
||||
Name string
|
||||
|
42
vendor/github.com/opencontainers/runc/libcontainer/user/user_fuzzer.go
generated
vendored
Normal file
42
vendor/github.com/opencontainers/runc/libcontainer/user/user_fuzzer.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
// +build gofuzz
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func IsDivisbleBy(n int, divisibleby int) bool {
|
||||
return (n % divisibleby) == 0
|
||||
}
|
||||
|
||||
func FuzzUser(data []byte) int {
|
||||
if len(data) == 0 {
|
||||
return -1
|
||||
}
|
||||
if !IsDivisbleBy(len(data), 5) {
|
||||
return -1
|
||||
}
|
||||
|
||||
var divided [][]byte
|
||||
|
||||
chunkSize := len(data) / 5
|
||||
|
||||
for i := 0; i < len(data); i += chunkSize {
|
||||
end := i + chunkSize
|
||||
|
||||
divided = append(divided, data[i:end])
|
||||
}
|
||||
|
||||
_, _ = ParsePasswdFilter(strings.NewReader(string(divided[0])), nil)
|
||||
|
||||
var passwd, group io.Reader
|
||||
|
||||
group = strings.NewReader(string(divided[1]))
|
||||
_, _ = GetAdditionalGroups([]string{string(divided[2])}, group)
|
||||
|
||||
passwd = strings.NewReader(string(divided[3]))
|
||||
_, _ = GetExecUser(string(divided[4]), nil, passwd, group)
|
||||
return 1
|
||||
}
|
13
vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
generated
vendored
13
vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
generated
vendored
@ -598,10 +598,13 @@ type VMImage struct {
|
||||
|
||||
// LinuxSeccomp represents syscall restrictions
|
||||
type LinuxSeccomp struct {
|
||||
DefaultAction LinuxSeccompAction `json:"defaultAction"`
|
||||
Architectures []Arch `json:"architectures,omitempty"`
|
||||
Flags []LinuxSeccompFlag `json:"flags,omitempty"`
|
||||
Syscalls []LinuxSyscall `json:"syscalls,omitempty"`
|
||||
DefaultAction LinuxSeccompAction `json:"defaultAction"`
|
||||
DefaultErrnoRet *uint `json:"defaultErrnoRet,omitempty"`
|
||||
Architectures []Arch `json:"architectures,omitempty"`
|
||||
Flags []LinuxSeccompFlag `json:"flags,omitempty"`
|
||||
ListenerPath string `json:"listenerPath,omitempty"`
|
||||
ListenerMetadata string `json:"listenerMetadata,omitempty"`
|
||||
Syscalls []LinuxSyscall `json:"syscalls,omitempty"`
|
||||
}
|
||||
|
||||
// Arch used for additional architectures
|
||||
@ -641,11 +644,13 @@ type LinuxSeccompAction string
|
||||
const (
|
||||
ActKill LinuxSeccompAction = "SCMP_ACT_KILL"
|
||||
ActKillProcess LinuxSeccompAction = "SCMP_ACT_KILL_PROCESS"
|
||||
ActKillThread LinuxSeccompAction = "SCMP_ACT_KILL_THREAD"
|
||||
ActTrap LinuxSeccompAction = "SCMP_ACT_TRAP"
|
||||
ActErrno LinuxSeccompAction = "SCMP_ACT_ERRNO"
|
||||
ActTrace LinuxSeccompAction = "SCMP_ACT_TRACE"
|
||||
ActAllow LinuxSeccompAction = "SCMP_ACT_ALLOW"
|
||||
ActLog LinuxSeccompAction = "SCMP_ACT_LOG"
|
||||
ActNotify LinuxSeccompAction = "SCMP_ACT_NOTIFY"
|
||||
)
|
||||
|
||||
// LinuxSeccompOperator used to match syscall arguments in Seccomp
|
||||
|
29
vendor/github.com/opencontainers/runtime-spec/specs-go/state.go
generated
vendored
29
vendor/github.com/opencontainers/runtime-spec/specs-go/state.go
generated
vendored
@ -5,17 +5,17 @@ type ContainerState string
|
||||
|
||||
const (
|
||||
// StateCreating indicates that the container is being created
|
||||
StateCreating ContainerState = "creating"
|
||||
StateCreating ContainerState = "creating"
|
||||
|
||||
// StateCreated indicates that the runtime has finished the create operation
|
||||
StateCreated ContainerState = "created"
|
||||
StateCreated ContainerState = "created"
|
||||
|
||||
// StateRunning indicates that the container process has executed the
|
||||
// user-specified program but has not exited
|
||||
StateRunning ContainerState = "running"
|
||||
StateRunning ContainerState = "running"
|
||||
|
||||
// StateStopped indicates that the container process has exited
|
||||
StateStopped ContainerState = "stopped"
|
||||
StateStopped ContainerState = "stopped"
|
||||
)
|
||||
|
||||
// State holds information about the runtime state of the container.
|
||||
@ -33,3 +33,24 @@ type State struct {
|
||||
// Annotations are key values associated with the container.
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
// SeccompFdName is the name of the seccomp notify file descriptor.
|
||||
SeccompFdName string = "seccompFd"
|
||||
)
|
||||
|
||||
// ContainerProcessState holds information about the state of a container process.
|
||||
type ContainerProcessState struct {
|
||||
// Version is the version of the specification that is supported.
|
||||
Version string `json:"ociVersion"`
|
||||
// Fds is a string array containing the names of the file descriptors passed.
|
||||
// The index of the name in this array corresponds to index of the file
|
||||
// descriptor in the `SCM_RIGHTS` array.
|
||||
Fds []string `json:"fds"`
|
||||
// Pid is the process ID as seen by the runtime.
|
||||
Pid int `json:"pid"`
|
||||
// Opaque metadata.
|
||||
Metadata string `json:"metadata,omitempty"`
|
||||
// State of the container.
|
||||
State State `json:"state"`
|
||||
}
|
||||
|
10
vendor/modules.txt
vendored
10
vendor/modules.txt
vendored
@ -45,7 +45,7 @@ github.com/Microsoft/hcsshim/pkg/ociwclayer
|
||||
github.com/beorn7/perks/quantile
|
||||
# github.com/cespare/xxhash/v2 v2.1.1
|
||||
github.com/cespare/xxhash/v2
|
||||
# github.com/cilium/ebpf v0.4.0
|
||||
# github.com/cilium/ebpf v0.5.0
|
||||
github.com/cilium/ebpf
|
||||
github.com/cilium/ebpf/asm
|
||||
github.com/cilium/ebpf/internal
|
||||
@ -134,7 +134,7 @@ github.com/containers/ocicrypt/keywrap/pkcs7
|
||||
github.com/containers/ocicrypt/spec
|
||||
github.com/containers/ocicrypt/utils
|
||||
github.com/containers/ocicrypt/utils/keyprovider
|
||||
# github.com/coreos/go-systemd/v22 v22.1.0
|
||||
# github.com/coreos/go-systemd/v22 v22.3.1
|
||||
## explicit
|
||||
github.com/coreos/go-systemd/v22/daemon
|
||||
github.com/coreos/go-systemd/v22/dbus
|
||||
@ -164,7 +164,7 @@ github.com/emicklei/go-restful/log
|
||||
github.com/fsnotify/fsnotify
|
||||
# github.com/go-logr/logr v0.2.0
|
||||
github.com/go-logr/logr
|
||||
# github.com/godbus/dbus/v5 v5.0.3
|
||||
# github.com/godbus/dbus/v5 v5.0.4
|
||||
github.com/godbus/dbus/v5
|
||||
# github.com/gogo/googleapis v1.4.0 => github.com/gogo/googleapis v1.3.2
|
||||
## explicit
|
||||
@ -268,10 +268,10 @@ github.com/opencontainers/go-digest/digestset
|
||||
github.com/opencontainers/image-spec/identity
|
||||
github.com/opencontainers/image-spec/specs-go
|
||||
github.com/opencontainers/image-spec/specs-go/v1
|
||||
# github.com/opencontainers/runc v1.0.0-rc93
|
||||
# github.com/opencontainers/runc v1.0.0-rc94
|
||||
## explicit
|
||||
github.com/opencontainers/runc/libcontainer/user
|
||||
# github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d
|
||||
# github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
|
||||
## explicit
|
||||
github.com/opencontainers/runtime-spec/specs-go
|
||||
# github.com/opencontainers/selinux v1.8.0
|
||||
|
Loading…
Reference in New Issue
Block a user