mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-29 08:47:56 +00:00
gpu: Fix cold-plug of VFIO devices
We need to do proper sandbox sizing when we're doing cold-plug introduce CDI, the de-facto standard for enabling devices in containers. containerd will pass-through annotations for accumulated CPU,Memory and now CDI devices. With that information sandbox sizing can be derived correctly. Fixes: #7331 Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
This commit is contained in:
parent
fcc755fc3b
commit
7c934dc7da
@ -7,6 +7,7 @@ require (
|
|||||||
github.com/BurntSushi/toml v1.2.0
|
github.com/BurntSushi/toml v1.2.0
|
||||||
github.com/blang/semver v3.5.1+incompatible
|
github.com/blang/semver v3.5.1+incompatible
|
||||||
github.com/blang/semver/v4 v4.0.0
|
github.com/blang/semver/v4 v4.0.0
|
||||||
|
github.com/container-orchestrated-devices/container-device-interface v0.6.0
|
||||||
github.com/containerd/cgroups v1.0.5-0.20220625035431-cf7417bca682
|
github.com/containerd/cgroups v1.0.5-0.20220625035431-cf7417bca682
|
||||||
github.com/containerd/console v1.0.3
|
github.com/containerd/console v1.0.3
|
||||||
github.com/containerd/containerd v1.6.8
|
github.com/containerd/containerd v1.6.8
|
||||||
@ -31,7 +32,7 @@ require (
|
|||||||
github.com/intel-go/cpuid v0.0.0-20210602155658-5747e5cec0d9
|
github.com/intel-go/cpuid v0.0.0-20210602155658-5747e5cec0d9
|
||||||
github.com/mdlayher/vsock v1.1.0
|
github.com/mdlayher/vsock v1.1.0
|
||||||
github.com/opencontainers/runc v1.1.3
|
github.com/opencontainers/runc v1.1.3
|
||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20211214071223-8958f93039ab
|
github.com/opencontainers/runtime-spec v1.1.0-rc.1
|
||||||
github.com/opencontainers/selinux v1.10.1
|
github.com/opencontainers/selinux v1.10.1
|
||||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
|
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
@ -51,7 +52,7 @@ require (
|
|||||||
go.opentelemetry.io/otel/sdk v1.3.0
|
go.opentelemetry.io/otel/sdk v1.3.0
|
||||||
go.opentelemetry.io/otel/trace v1.3.0
|
go.opentelemetry.io/otel/trace v1.3.0
|
||||||
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2
|
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
|
golang.org/x/sys v0.1.0
|
||||||
google.golang.org/grpc v1.47.0
|
google.golang.org/grpc v1.47.0
|
||||||
k8s.io/apimachinery v0.22.5
|
k8s.io/apimachinery v0.22.5
|
||||||
k8s.io/cri-api v0.23.1
|
k8s.io/cri-api v0.23.1
|
||||||
@ -93,11 +94,14 @@ require (
|
|||||||
github.com/oklog/ulid v1.3.1 // indirect
|
github.com/oklog/ulid v1.3.1 // indirect
|
||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 // indirect
|
github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 // indirect
|
||||||
|
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.8.1-0.20210923151022-86f73c517451 // indirect
|
github.com/rogpeppe/go-internal v1.8.1-0.20210923151022-86f73c517451 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
|
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
|
||||||
go.mongodb.org/mongo-driver v1.7.5 // indirect
|
go.mongodb.org/mongo-driver v1.7.5 // indirect
|
||||||
go.opencensus.io v0.23.0 // indirect
|
go.opencensus.io v0.23.0 // indirect
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
||||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
|
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
|
||||||
golang.org/x/text v0.3.7 // indirect
|
golang.org/x/text v0.3.7 // indirect
|
||||||
@ -107,6 +111,7 @@ require (
|
|||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace (
|
replace (
|
||||||
|
@ -248,6 +248,8 @@ github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoC
|
|||||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
||||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
|
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
|
||||||
github.com/container-orchestrated-devices/container-device-interface v0.4.0/go.mod h1:E1zcucIkq9P3eyNmY+68dBQsTcsXJh9cgRo2IVNScKQ=
|
github.com/container-orchestrated-devices/container-device-interface v0.4.0/go.mod h1:E1zcucIkq9P3eyNmY+68dBQsTcsXJh9cgRo2IVNScKQ=
|
||||||
|
github.com/container-orchestrated-devices/container-device-interface v0.6.0 h1:aWwcz/Ep0Fd7ZuBjQGjU/jdPloM7ydhMW13h85jZNvk=
|
||||||
|
github.com/container-orchestrated-devices/container-device-interface v0.6.0/go.mod h1:OQlgtJtDrOxSQ1BWODC8OZK1tzi9W69wek+Jy17ndzo=
|
||||||
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
|
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
|
||||||
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
|
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
|
||||||
github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||||
@ -1205,11 +1207,15 @@ github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/
|
|||||||
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.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20201121164853-7413a7f753e1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.3-0.20201121164853-7413a7f753e1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20211214071223-8958f93039ab h1:YQZXa3elcHgKXAa2GjVFC9M3JeP7ZPyFD1YByDx/dgQ=
|
|
||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20211214071223-8958f93039ab/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.3-0.20211214071223-8958f93039ab/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
|
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
|
github.com/opencontainers/runtime-spec v1.1.0-rc.1 h1:wHa9jroFfKGQqFHj0I1fMRKLl0pfj+ynAqBxo3v6u9w=
|
||||||
|
github.com/opencontainers/runtime-spec v1.1.0-rc.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
||||||
github.com/opencontainers/runtime-tools v0.0.0-20190417131837-cd1349b7c47e/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
github.com/opencontainers/runtime-tools v0.0.0-20190417131837-cd1349b7c47e/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
||||||
github.com/opencontainers/runtime-tools v0.9.1-0.20220714195903-17b3287fafb7/go.mod h1:/tgP02fPXGHkU3/qKK1Y0Db4yqNyGm03vLq/mzHzcS4=
|
github.com/opencontainers/runtime-tools v0.9.1-0.20220714195903-17b3287fafb7/go.mod h1:/tgP02fPXGHkU3/qKK1Y0Db4yqNyGm03vLq/mzHzcS4=
|
||||||
|
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 h1:DmNGcqH3WDbV5k8OJ+esPWbqUOX5rMLR2PMvziDMJi0=
|
||||||
|
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI=
|
||||||
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
|
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
|
||||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
||||||
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
|
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
|
||||||
@ -1401,6 +1407,7 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69
|
|||||||
github.com/sylabs/sif/v2 v2.7.1/go.mod h1:bBse2nEFd3yHkmq6KmAOFEWQg5LdFYiQUdVcgamxlc8=
|
github.com/sylabs/sif/v2 v2.7.1/go.mod h1:bBse2nEFd3yHkmq6KmAOFEWQg5LdFYiQUdVcgamxlc8=
|
||||||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
|
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
|
||||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
|
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
|
||||||
@ -1459,9 +1466,12 @@ github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6
|
|||||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||||
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
||||||
|
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
@ -1629,6 +1639,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||||
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@ -1893,8 +1904,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
@ -2230,4 +2241,5 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
|
|||||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
||||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||||
|
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
||||||
containerd_types "github.com/containerd/containerd/api/types"
|
containerd_types "github.com/containerd/containerd/api/types"
|
||||||
"github.com/containerd/containerd/mount"
|
"github.com/containerd/containerd/mount"
|
||||||
taskAPI "github.com/containerd/containerd/runtime/v2/task"
|
taskAPI "github.com/containerd/containerd/runtime/v2/task"
|
||||||
@ -73,6 +74,63 @@ func copyLayersToMounts(rootFs *vc.RootFs, spec *specs.Spec) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CDI (Container Device Interface), is a specification, for container- runtimes,
|
||||||
|
// to support third-party devices.
|
||||||
|
// It introduces an abstract notion of a device as a resource. Such devices are
|
||||||
|
// uniquely specified by a fully-qualified name that is constructed from a
|
||||||
|
// vendor ID, a device class, and a name that is unique per vendor ID-device
|
||||||
|
// class pair.
|
||||||
|
//
|
||||||
|
// vendor.com/class=unique_name
|
||||||
|
//
|
||||||
|
// The combination of vendor ID and device class (vendor.com/class in the
|
||||||
|
// above example) is referred to as the device kind.
|
||||||
|
// CDI concerns itself only with enabling containers to be device aware.
|
||||||
|
// Areas like resource management are explicitly left out of CDI (and are
|
||||||
|
// expected to be handled by the orchestrator). Because of this focus, the CDI
|
||||||
|
// specification is simple to implement and allows great flexibility for
|
||||||
|
// runtimes and orchestrators.
|
||||||
|
func withCDI(annotations map[string]string, cdiSpecDirs []string, spec *specs.Spec) (*specs.Spec, error) {
|
||||||
|
// Add devices from CDI annotations
|
||||||
|
_, devsFromAnnotations, err := cdi.ParseAnnotations(annotations)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse CDI device annotations: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(devsFromAnnotations) == 0 {
|
||||||
|
// No devices found, skip device injection
|
||||||
|
return spec, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var registry cdi.Registry
|
||||||
|
if len(cdiSpecDirs) > 0 {
|
||||||
|
// We can override the directories where to search for CDI specs
|
||||||
|
// if needed, the default is /etc/cdi /var/run/cdi
|
||||||
|
registry = cdi.GetRegistry(cdi.WithSpecDirs(cdiSpecDirs...))
|
||||||
|
} else {
|
||||||
|
registry = cdi.GetRegistry()
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = registry.Refresh(); err != nil {
|
||||||
|
// We don't consider registry refresh failure a fatal error.
|
||||||
|
// For instance, a dynamically generated invalid CDI Spec file for
|
||||||
|
// any particular vendor shouldn't prevent injection of devices of
|
||||||
|
// different vendors. CDI itself knows better and it will fail the
|
||||||
|
// injection if necessary.
|
||||||
|
return nil, fmt.Errorf("CDI registry refresh failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := registry.InjectDevices(spec, devsFromAnnotations...); err != nil {
|
||||||
|
return nil, fmt.Errorf("CDI device injection failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// One crucial thing to keep in mind is that CDI device injection
|
||||||
|
// might add OCI Spec environment variables, hooks, and mounts as
|
||||||
|
// well. Therefore it is important that none of the corresponding
|
||||||
|
// OCI Spec fields are reset up in the call stack once we return.
|
||||||
|
return spec, nil
|
||||||
|
}
|
||||||
|
|
||||||
func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*container, error) {
|
func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*container, error) {
|
||||||
rootFs := vc.RootFs{}
|
rootFs := vc.RootFs{}
|
||||||
if len(r.Rootfs) == 1 {
|
if len(r.Rootfs) == 1 {
|
||||||
@ -111,6 +169,16 @@ func create(ctx context.Context, s *service, r *taskAPI.CreateTaskRequest) (*con
|
|||||||
if s.sandbox != nil {
|
if s.sandbox != nil {
|
||||||
return nil, fmt.Errorf("cannot create another sandbox in sandbox: %s", s.sandbox.ID())
|
return nil, fmt.Errorf("cannot create another sandbox in sandbox: %s", s.sandbox.ID())
|
||||||
}
|
}
|
||||||
|
// We can provide additional directories where to search for
|
||||||
|
// CDI specs if needed. immutable OS's only have specific
|
||||||
|
// directories where applications can write too. For instance /opt/cdi
|
||||||
|
//
|
||||||
|
// _, err = withCDI(ociSpec.Annotations, []string{"/opt/cdi"}, ociSpec)
|
||||||
|
//
|
||||||
|
_, err = withCDI(ociSpec.Annotations, []string{}, ociSpec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("adding CDI devices failed")
|
||||||
|
}
|
||||||
|
|
||||||
s.config = runtimeConfig
|
s.config = runtimeConfig
|
||||||
|
|
||||||
|
201
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/LICENSE
generated
vendored
Normal file
201
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/LICENSE
generated
vendored
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
82
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/internal/multierror/multierror.go
generated
vendored
Normal file
82
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/internal/multierror/multierror.go
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2022 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package multierror
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// New combines several errors into a single error. Parameters that are nil are
|
||||||
|
// ignored. If no errors are passed in or all parameters are nil, then the
|
||||||
|
// result is also nil.
|
||||||
|
func New(errors ...error) error {
|
||||||
|
// Filter out nil entries.
|
||||||
|
numErrors := 0
|
||||||
|
for _, err := range errors {
|
||||||
|
if err != nil {
|
||||||
|
errors[numErrors] = err
|
||||||
|
numErrors++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if numErrors == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return multiError(errors[0:numErrors])
|
||||||
|
}
|
||||||
|
|
||||||
|
// multiError is the underlying implementation used by New.
|
||||||
|
//
|
||||||
|
// Beware that a null multiError is not the same as a nil error.
|
||||||
|
type multiError []error
|
||||||
|
|
||||||
|
// multiError returns all individual error strings concatenated with "\n"
|
||||||
|
func (e multiError) Error() string {
|
||||||
|
var builder strings.Builder
|
||||||
|
for i, err := range e {
|
||||||
|
if i > 0 {
|
||||||
|
_, _ = builder.WriteString("\n")
|
||||||
|
}
|
||||||
|
_, _ = builder.WriteString(err.Error())
|
||||||
|
}
|
||||||
|
return builder.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append returns a new multi error all errors concatenated. Errors that are
|
||||||
|
// multi errors get flattened, nil is ignored.
|
||||||
|
func Append(err error, errors ...error) error {
|
||||||
|
var result multiError
|
||||||
|
if m, ok := err.(multiError); ok {
|
||||||
|
result = m
|
||||||
|
} else if err != nil {
|
||||||
|
result = append(result, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, e := range errors {
|
||||||
|
if e == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if m, ok := e.(multiError); ok {
|
||||||
|
result = append(result, m...)
|
||||||
|
} else {
|
||||||
|
result = append(result, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(result) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
57
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/internal/validation/k8s/objectmeta.go
generated
vendored
Normal file
57
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/internal/validation/k8s/objectmeta.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Adapted from k8s.io/apimachinery/pkg/api/validation:
|
||||||
|
// https://github.com/kubernetes/apimachinery/blob/7687996c715ee7d5c8cf1e3215e607eb065a4221/pkg/api/validation/objectmeta.go
|
||||||
|
|
||||||
|
package k8s
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/container-orchestrated-devices/container-device-interface/internal/multierror"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TotalAnnotationSizeLimitB defines the maximum size of all annotations in characters.
|
||||||
|
const TotalAnnotationSizeLimitB int = 256 * (1 << 10) // 256 kB
|
||||||
|
|
||||||
|
// ValidateAnnotations validates that a set of annotations are correctly defined.
|
||||||
|
func ValidateAnnotations(annotations map[string]string, path string) error {
|
||||||
|
errors := multierror.New()
|
||||||
|
for k := range annotations {
|
||||||
|
// The rule is QualifiedName except that case doesn't matter, so convert to lowercase before checking.
|
||||||
|
for _, msg := range IsQualifiedName(strings.ToLower(k)) {
|
||||||
|
errors = multierror.Append(errors, fmt.Errorf("%v.%v is invalid: %v", path, k, msg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := ValidateAnnotationsSize(annotations); err != nil {
|
||||||
|
errors = multierror.Append(errors, fmt.Errorf("%v is too long: %v", path, err))
|
||||||
|
}
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateAnnotationsSize validates that a set of annotations is not too large.
|
||||||
|
func ValidateAnnotationsSize(annotations map[string]string) error {
|
||||||
|
var totalSize int64
|
||||||
|
for k, v := range annotations {
|
||||||
|
totalSize += (int64)(len(k)) + (int64)(len(v))
|
||||||
|
}
|
||||||
|
if totalSize > (int64)(TotalAnnotationSizeLimitB) {
|
||||||
|
return fmt.Errorf("annotations size %d is larger than limit %d", totalSize, TotalAnnotationSizeLimitB)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
217
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/internal/validation/k8s/validation.go
generated
vendored
Normal file
217
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/internal/validation/k8s/validation.go
generated
vendored
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Adapted from k8s.io/apimachinery/pkg/util/validation:
|
||||||
|
// https://github.com/kubernetes/apimachinery/blob/7687996c715ee7d5c8cf1e3215e607eb065a4221/pkg/util/validation/validation.go
|
||||||
|
|
||||||
|
package k8s
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const qnameCharFmt string = "[A-Za-z0-9]"
|
||||||
|
const qnameExtCharFmt string = "[-A-Za-z0-9_.]"
|
||||||
|
const qualifiedNameFmt string = "(" + qnameCharFmt + qnameExtCharFmt + "*)?" + qnameCharFmt
|
||||||
|
const qualifiedNameErrMsg string = "must consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character"
|
||||||
|
const qualifiedNameMaxLength int = 63
|
||||||
|
|
||||||
|
var qualifiedNameRegexp = regexp.MustCompile("^" + qualifiedNameFmt + "$")
|
||||||
|
|
||||||
|
// IsQualifiedName tests whether the value passed is what Kubernetes calls a
|
||||||
|
// "qualified name". This is a format used in various places throughout the
|
||||||
|
// system. If the value is not valid, a list of error strings is returned.
|
||||||
|
// Otherwise an empty list (or nil) is returned.
|
||||||
|
func IsQualifiedName(value string) []string {
|
||||||
|
var errs []string
|
||||||
|
parts := strings.Split(value, "/")
|
||||||
|
var name string
|
||||||
|
switch len(parts) {
|
||||||
|
case 1:
|
||||||
|
name = parts[0]
|
||||||
|
case 2:
|
||||||
|
var prefix string
|
||||||
|
prefix, name = parts[0], parts[1]
|
||||||
|
if len(prefix) == 0 {
|
||||||
|
errs = append(errs, "prefix part "+EmptyError())
|
||||||
|
} else if msgs := IsDNS1123Subdomain(prefix); len(msgs) != 0 {
|
||||||
|
errs = append(errs, prefixEach(msgs, "prefix part ")...)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return append(errs, "a qualified name "+RegexError(qualifiedNameErrMsg, qualifiedNameFmt, "MyName", "my.name", "123-abc")+
|
||||||
|
" with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(name) == 0 {
|
||||||
|
errs = append(errs, "name part "+EmptyError())
|
||||||
|
} else if len(name) > qualifiedNameMaxLength {
|
||||||
|
errs = append(errs, "name part "+MaxLenError(qualifiedNameMaxLength))
|
||||||
|
}
|
||||||
|
if !qualifiedNameRegexp.MatchString(name) {
|
||||||
|
errs = append(errs, "name part "+RegexError(qualifiedNameErrMsg, qualifiedNameFmt, "MyName", "my.name", "123-abc"))
|
||||||
|
}
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
const labelValueFmt string = "(" + qualifiedNameFmt + ")?"
|
||||||
|
const labelValueErrMsg string = "a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character"
|
||||||
|
|
||||||
|
// LabelValueMaxLength is a label's max length
|
||||||
|
const LabelValueMaxLength int = 63
|
||||||
|
|
||||||
|
var labelValueRegexp = regexp.MustCompile("^" + labelValueFmt + "$")
|
||||||
|
|
||||||
|
// IsValidLabelValue tests whether the value passed is a valid label value. If
|
||||||
|
// the value is not valid, a list of error strings is returned. Otherwise an
|
||||||
|
// empty list (or nil) is returned.
|
||||||
|
func IsValidLabelValue(value string) []string {
|
||||||
|
var errs []string
|
||||||
|
if len(value) > LabelValueMaxLength {
|
||||||
|
errs = append(errs, MaxLenError(LabelValueMaxLength))
|
||||||
|
}
|
||||||
|
if !labelValueRegexp.MatchString(value) {
|
||||||
|
errs = append(errs, RegexError(labelValueErrMsg, labelValueFmt, "MyValue", "my_value", "12345"))
|
||||||
|
}
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
const dns1123LabelFmt string = "[a-z0-9]([-a-z0-9]*[a-z0-9])?"
|
||||||
|
const dns1123LabelErrMsg string = "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character"
|
||||||
|
|
||||||
|
// DNS1123LabelMaxLength is a label's max length in DNS (RFC 1123)
|
||||||
|
const DNS1123LabelMaxLength int = 63
|
||||||
|
|
||||||
|
var dns1123LabelRegexp = regexp.MustCompile("^" + dns1123LabelFmt + "$")
|
||||||
|
|
||||||
|
// IsDNS1123Label tests for a string that conforms to the definition of a label in
|
||||||
|
// DNS (RFC 1123).
|
||||||
|
func IsDNS1123Label(value string) []string {
|
||||||
|
var errs []string
|
||||||
|
if len(value) > DNS1123LabelMaxLength {
|
||||||
|
errs = append(errs, MaxLenError(DNS1123LabelMaxLength))
|
||||||
|
}
|
||||||
|
if !dns1123LabelRegexp.MatchString(value) {
|
||||||
|
errs = append(errs, RegexError(dns1123LabelErrMsg, dns1123LabelFmt, "my-name", "123-abc"))
|
||||||
|
}
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
const dns1123SubdomainFmt string = dns1123LabelFmt + "(\\." + dns1123LabelFmt + ")*"
|
||||||
|
const dns1123SubdomainErrorMsg string = "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character"
|
||||||
|
|
||||||
|
// DNS1123SubdomainMaxLength is a subdomain's max length in DNS (RFC 1123)
|
||||||
|
const DNS1123SubdomainMaxLength int = 253
|
||||||
|
|
||||||
|
var dns1123SubdomainRegexp = regexp.MustCompile("^" + dns1123SubdomainFmt + "$")
|
||||||
|
|
||||||
|
// IsDNS1123Subdomain tests for a string that conforms to the definition of a
|
||||||
|
// subdomain in DNS (RFC 1123).
|
||||||
|
func IsDNS1123Subdomain(value string) []string {
|
||||||
|
var errs []string
|
||||||
|
if len(value) > DNS1123SubdomainMaxLength {
|
||||||
|
errs = append(errs, MaxLenError(DNS1123SubdomainMaxLength))
|
||||||
|
}
|
||||||
|
if !dns1123SubdomainRegexp.MatchString(value) {
|
||||||
|
errs = append(errs, RegexError(dns1123SubdomainErrorMsg, dns1123SubdomainFmt, "example.com"))
|
||||||
|
}
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
const dns1035LabelFmt string = "[a-z]([-a-z0-9]*[a-z0-9])?"
|
||||||
|
const dns1035LabelErrMsg string = "a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character"
|
||||||
|
|
||||||
|
// DNS1035LabelMaxLength is a label's max length in DNS (RFC 1035)
|
||||||
|
const DNS1035LabelMaxLength int = 63
|
||||||
|
|
||||||
|
var dns1035LabelRegexp = regexp.MustCompile("^" + dns1035LabelFmt + "$")
|
||||||
|
|
||||||
|
// IsDNS1035Label tests for a string that conforms to the definition of a label in
|
||||||
|
// DNS (RFC 1035).
|
||||||
|
func IsDNS1035Label(value string) []string {
|
||||||
|
var errs []string
|
||||||
|
if len(value) > DNS1035LabelMaxLength {
|
||||||
|
errs = append(errs, MaxLenError(DNS1035LabelMaxLength))
|
||||||
|
}
|
||||||
|
if !dns1035LabelRegexp.MatchString(value) {
|
||||||
|
errs = append(errs, RegexError(dns1035LabelErrMsg, dns1035LabelFmt, "my-name", "abc-123"))
|
||||||
|
}
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
// wildcard definition - RFC 1034 section 4.3.3.
|
||||||
|
// examples:
|
||||||
|
// - valid: *.bar.com, *.foo.bar.com
|
||||||
|
// - invalid: *.*.bar.com, *.foo.*.com, *bar.com, f*.bar.com, *
|
||||||
|
const wildcardDNS1123SubdomainFmt = "\\*\\." + dns1123SubdomainFmt
|
||||||
|
const wildcardDNS1123SubdomainErrMsg = "a wildcard DNS-1123 subdomain must start with '*.', followed by a valid DNS subdomain, which must consist of lower case alphanumeric characters, '-' or '.' and end with an alphanumeric character"
|
||||||
|
|
||||||
|
// IsWildcardDNS1123Subdomain tests for a string that conforms to the definition of a
|
||||||
|
// wildcard subdomain in DNS (RFC 1034 section 4.3.3).
|
||||||
|
func IsWildcardDNS1123Subdomain(value string) []string {
|
||||||
|
wildcardDNS1123SubdomainRegexp := regexp.MustCompile("^" + wildcardDNS1123SubdomainFmt + "$")
|
||||||
|
|
||||||
|
var errs []string
|
||||||
|
if len(value) > DNS1123SubdomainMaxLength {
|
||||||
|
errs = append(errs, MaxLenError(DNS1123SubdomainMaxLength))
|
||||||
|
}
|
||||||
|
if !wildcardDNS1123SubdomainRegexp.MatchString(value) {
|
||||||
|
errs = append(errs, RegexError(wildcardDNS1123SubdomainErrMsg, wildcardDNS1123SubdomainFmt, "*.example.com"))
|
||||||
|
}
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaxLenError returns a string explanation of a "string too long" validation
|
||||||
|
// failure.
|
||||||
|
func MaxLenError(length int) string {
|
||||||
|
return fmt.Sprintf("must be no more than %d characters", length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegexError returns a string explanation of a regex validation failure.
|
||||||
|
func RegexError(msg string, fmt string, examples ...string) string {
|
||||||
|
if len(examples) == 0 {
|
||||||
|
return msg + " (regex used for validation is '" + fmt + "')"
|
||||||
|
}
|
||||||
|
msg += " (e.g. "
|
||||||
|
for i := range examples {
|
||||||
|
if i > 0 {
|
||||||
|
msg += " or "
|
||||||
|
}
|
||||||
|
msg += "'" + examples[i] + "', "
|
||||||
|
}
|
||||||
|
msg += "regex used for validation is '" + fmt + "')"
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// EmptyError returns a string explanation of a "must not be empty" validation
|
||||||
|
// failure.
|
||||||
|
func EmptyError() string {
|
||||||
|
return "must be non-empty"
|
||||||
|
}
|
||||||
|
|
||||||
|
func prefixEach(msgs []string, prefix string) []string {
|
||||||
|
for i := range msgs {
|
||||||
|
msgs[i] = prefix + msgs[i]
|
||||||
|
}
|
||||||
|
return msgs
|
||||||
|
}
|
||||||
|
|
||||||
|
// InclusiveRangeError returns a string explanation of a numeric "must be
|
||||||
|
// between" validation failure.
|
||||||
|
func InclusiveRangeError(lo, hi int) string {
|
||||||
|
return fmt.Sprintf(`must be between %d and %d, inclusive`, lo, hi)
|
||||||
|
}
|
56
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/internal/validation/validate.go
generated
vendored
Normal file
56
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/internal/validation/validate.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
Copyright © The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package validation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/container-orchestrated-devices/container-device-interface/internal/validation/k8s"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ValidateSpecAnnotations checks whether spec annotations are valid.
|
||||||
|
func ValidateSpecAnnotations(name string, any interface{}) error {
|
||||||
|
if any == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v := any.(type) {
|
||||||
|
case map[string]interface{}:
|
||||||
|
annotations := make(map[string]string)
|
||||||
|
for k, v := range v {
|
||||||
|
if s, ok := v.(string); ok {
|
||||||
|
annotations[k] = s
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("invalid annotation %v.%v; %v is not a string", name, k, any)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return validateSpecAnnotations(name, annotations)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateSpecAnnotations checks whether spec annotations are valid.
|
||||||
|
func validateSpecAnnotations(name string, annotations map[string]string) error {
|
||||||
|
path := "annotations"
|
||||||
|
if name != "" {
|
||||||
|
path = strings.Join([]string{name, path}, ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
return k8s.ValidateAnnotations(annotations, path)
|
||||||
|
}
|
141
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/annotations.go
generated
vendored
Normal file
141
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/annotations.go
generated
vendored
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2021-2022 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/container-orchestrated-devices/container-device-interface/pkg/parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// AnnotationPrefix is the prefix for CDI container annotation keys.
|
||||||
|
AnnotationPrefix = "cdi.k8s.io/"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UpdateAnnotations updates annotations with a plugin-specific CDI device
|
||||||
|
// injection request for the given devices. Upon any error a non-nil error
|
||||||
|
// is returned and annotations are left intact. By convention plugin should
|
||||||
|
// be in the format of "vendor.device-type".
|
||||||
|
func UpdateAnnotations(annotations map[string]string, plugin string, deviceID string, devices []string) (map[string]string, error) {
|
||||||
|
key, err := AnnotationKey(plugin, deviceID)
|
||||||
|
if err != nil {
|
||||||
|
return annotations, fmt.Errorf("CDI annotation failed: %w", err)
|
||||||
|
}
|
||||||
|
if _, ok := annotations[key]; ok {
|
||||||
|
return annotations, fmt.Errorf("CDI annotation failed, key %q used", key)
|
||||||
|
}
|
||||||
|
value, err := AnnotationValue(devices)
|
||||||
|
if err != nil {
|
||||||
|
return annotations, fmt.Errorf("CDI annotation failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if annotations == nil {
|
||||||
|
annotations = make(map[string]string)
|
||||||
|
}
|
||||||
|
annotations[key] = value
|
||||||
|
|
||||||
|
return annotations, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseAnnotations parses annotations for CDI device injection requests.
|
||||||
|
// The keys and devices from all such requests are collected into slices
|
||||||
|
// which are returned as the result. All devices are expected to be fully
|
||||||
|
// qualified CDI device names. If any device fails this check empty slices
|
||||||
|
// are returned along with a non-nil error. The annotations are expected
|
||||||
|
// to be formatted by, or in a compatible fashion to UpdateAnnotations().
|
||||||
|
func ParseAnnotations(annotations map[string]string) ([]string, []string, error) {
|
||||||
|
var (
|
||||||
|
keys []string
|
||||||
|
devices []string
|
||||||
|
)
|
||||||
|
|
||||||
|
for key, value := range annotations {
|
||||||
|
if !strings.HasPrefix(key, AnnotationPrefix) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, d := range strings.Split(value, ",") {
|
||||||
|
if !IsQualifiedName(d) {
|
||||||
|
return nil, nil, fmt.Errorf("invalid CDI device name %q", d)
|
||||||
|
}
|
||||||
|
devices = append(devices, d)
|
||||||
|
}
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys, devices, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnnotationKey returns a unique annotation key for an device allocation
|
||||||
|
// by a K8s device plugin. pluginName should be in the format of
|
||||||
|
// "vendor.device-type". deviceID is the ID of the device the plugin is
|
||||||
|
// allocating. It is used to make sure that the generated key is unique
|
||||||
|
// even if multiple allocations by a single plugin needs to be annotated.
|
||||||
|
func AnnotationKey(pluginName, deviceID string) (string, error) {
|
||||||
|
const maxNameLen = 63
|
||||||
|
|
||||||
|
if pluginName == "" {
|
||||||
|
return "", errors.New("invalid plugin name, empty")
|
||||||
|
}
|
||||||
|
if deviceID == "" {
|
||||||
|
return "", errors.New("invalid deviceID, empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
name := pluginName + "_" + strings.ReplaceAll(deviceID, "/", "_")
|
||||||
|
|
||||||
|
if len(name) > maxNameLen {
|
||||||
|
return "", fmt.Errorf("invalid plugin+deviceID %q, too long", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c := rune(name[0]); !parser.IsAlphaNumeric(c) {
|
||||||
|
return "", fmt.Errorf("invalid name %q, first '%c' should be alphanumeric",
|
||||||
|
name, c)
|
||||||
|
}
|
||||||
|
if len(name) > 2 {
|
||||||
|
for _, c := range name[1 : len(name)-1] {
|
||||||
|
switch {
|
||||||
|
case parser.IsAlphaNumeric(c):
|
||||||
|
case c == '_' || c == '-' || c == '.':
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("invalid name %q, invalid character '%c'",
|
||||||
|
name, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c := rune(name[len(name)-1]); !parser.IsAlphaNumeric(c) {
|
||||||
|
return "", fmt.Errorf("invalid name %q, last '%c' should be alphanumeric",
|
||||||
|
name, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
return AnnotationPrefix + name, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnnotationValue returns an annotation value for the given devices.
|
||||||
|
func AnnotationValue(devices []string) (string, error) {
|
||||||
|
value, sep := "", ""
|
||||||
|
for _, d := range devices {
|
||||||
|
if _, _, _, err := ParseQualifiedName(d); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
value += sep + d
|
||||||
|
sep = ","
|
||||||
|
}
|
||||||
|
|
||||||
|
return value, nil
|
||||||
|
}
|
581
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache.go
generated
vendored
Normal file
581
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache.go
generated
vendored
Normal file
@ -0,0 +1,581 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/container-orchestrated-devices/container-device-interface/internal/multierror"
|
||||||
|
cdi "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
|
"github.com/fsnotify/fsnotify"
|
||||||
|
oci "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Option is an option to change some aspect of default CDI behavior.
|
||||||
|
type Option func(*Cache) error
|
||||||
|
|
||||||
|
// Cache stores CDI Specs loaded from Spec directories.
|
||||||
|
type Cache struct {
|
||||||
|
sync.Mutex
|
||||||
|
specDirs []string
|
||||||
|
specs map[string][]*Spec
|
||||||
|
devices map[string]*Device
|
||||||
|
errors map[string][]error
|
||||||
|
dirErrors map[string]error
|
||||||
|
|
||||||
|
autoRefresh bool
|
||||||
|
watch *watch
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAutoRefresh returns an option to control automatic Cache refresh.
|
||||||
|
// By default auto-refresh is enabled, the list of Spec directories are
|
||||||
|
// monitored and the Cache is automatically refreshed whenever a change
|
||||||
|
// is detected. This option can be used to disable this behavior when a
|
||||||
|
// manually refreshed mode is preferable.
|
||||||
|
func WithAutoRefresh(autoRefresh bool) Option {
|
||||||
|
return func(c *Cache) error {
|
||||||
|
c.autoRefresh = autoRefresh
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCache creates a new CDI Cache. The cache is populated from a set
|
||||||
|
// of CDI Spec directories. These can be specified using a WithSpecDirs
|
||||||
|
// option. The default set of directories is exposed in DefaultSpecDirs.
|
||||||
|
func NewCache(options ...Option) (*Cache, error) {
|
||||||
|
c := &Cache{
|
||||||
|
autoRefresh: true,
|
||||||
|
watch: &watch{},
|
||||||
|
}
|
||||||
|
|
||||||
|
WithSpecDirs(DefaultSpecDirs...)(c)
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
return c, c.configure(options...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure applies options to the Cache. Updates and refreshes the
|
||||||
|
// Cache if options have changed.
|
||||||
|
func (c *Cache) Configure(options ...Option) error {
|
||||||
|
if len(options) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
return c.configure(options...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure the Cache. Start/stop CDI Spec directory watch, refresh
|
||||||
|
// the Cache if necessary.
|
||||||
|
func (c *Cache) configure(options ...Option) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
for _, o := range options {
|
||||||
|
if err = o(c); err != nil {
|
||||||
|
return fmt.Errorf("failed to apply cache options: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.dirErrors = make(map[string]error)
|
||||||
|
|
||||||
|
c.watch.stop()
|
||||||
|
if c.autoRefresh {
|
||||||
|
c.watch.setup(c.specDirs, c.dirErrors)
|
||||||
|
c.watch.start(&c.Mutex, c.refresh, c.dirErrors)
|
||||||
|
}
|
||||||
|
c.refresh()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh rescans the CDI Spec directories and refreshes the Cache.
|
||||||
|
// In manual refresh mode the cache is always refreshed. In auto-
|
||||||
|
// refresh mode the cache is only refreshed if it is out of date.
|
||||||
|
func (c *Cache) Refresh() error {
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
// force a refresh in manual mode
|
||||||
|
if refreshed, err := c.refreshIfRequired(!c.autoRefresh); refreshed {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// collect and return cached errors, much like refresh() does it
|
||||||
|
var result error
|
||||||
|
for _, errors := range c.errors {
|
||||||
|
result = multierror.Append(result, errors...)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh the Cache by rescanning CDI Spec directories and files.
|
||||||
|
func (c *Cache) refresh() error {
|
||||||
|
var (
|
||||||
|
specs = map[string][]*Spec{}
|
||||||
|
devices = map[string]*Device{}
|
||||||
|
conflicts = map[string]struct{}{}
|
||||||
|
specErrors = map[string][]error{}
|
||||||
|
result []error
|
||||||
|
)
|
||||||
|
|
||||||
|
// collect errors per spec file path and once globally
|
||||||
|
collectError := func(err error, paths ...string) {
|
||||||
|
result = append(result, err)
|
||||||
|
for _, path := range paths {
|
||||||
|
specErrors[path] = append(specErrors[path], err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// resolve conflicts based on device Spec priority (order of precedence)
|
||||||
|
resolveConflict := func(name string, dev *Device, old *Device) bool {
|
||||||
|
devSpec, oldSpec := dev.GetSpec(), old.GetSpec()
|
||||||
|
devPrio, oldPrio := devSpec.GetPriority(), oldSpec.GetPriority()
|
||||||
|
switch {
|
||||||
|
case devPrio > oldPrio:
|
||||||
|
return false
|
||||||
|
case devPrio == oldPrio:
|
||||||
|
devPath, oldPath := devSpec.GetPath(), oldSpec.GetPath()
|
||||||
|
collectError(fmt.Errorf("conflicting device %q (specs %q, %q)",
|
||||||
|
name, devPath, oldPath), devPath, oldPath)
|
||||||
|
conflicts[name] = struct{}{}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = scanSpecDirs(c.specDirs, func(path string, priority int, spec *Spec, err error) error {
|
||||||
|
path = filepath.Clean(path)
|
||||||
|
if err != nil {
|
||||||
|
collectError(fmt.Errorf("failed to load CDI Spec %w", err), path)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
vendor := spec.GetVendor()
|
||||||
|
specs[vendor] = append(specs[vendor], spec)
|
||||||
|
|
||||||
|
for _, dev := range spec.devices {
|
||||||
|
qualified := dev.GetQualifiedName()
|
||||||
|
other, ok := devices[qualified]
|
||||||
|
if ok {
|
||||||
|
if resolveConflict(qualified, dev, other) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
devices[qualified] = dev
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
for conflict := range conflicts {
|
||||||
|
delete(devices, conflict)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.specs = specs
|
||||||
|
c.devices = devices
|
||||||
|
c.errors = specErrors
|
||||||
|
|
||||||
|
return multierror.New(result...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RefreshIfRequired triggers a refresh if necessary.
|
||||||
|
func (c *Cache) refreshIfRequired(force bool) (bool, error) {
|
||||||
|
// We need to refresh if
|
||||||
|
// - it's forced by an explicitly call to Refresh() in manual mode
|
||||||
|
// - a missing Spec dir appears (added to watch) in auto-refresh mode
|
||||||
|
if force || (c.autoRefresh && c.watch.update(c.dirErrors)) {
|
||||||
|
return true, c.refresh()
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// InjectDevices injects the given qualified devices to an OCI Spec. It
|
||||||
|
// returns any unresolvable devices and an error if injection fails for
|
||||||
|
// any of the devices.
|
||||||
|
func (c *Cache) InjectDevices(ociSpec *oci.Spec, devices ...string) ([]string, error) {
|
||||||
|
var unresolved []string
|
||||||
|
|
||||||
|
if ociSpec == nil {
|
||||||
|
return devices, fmt.Errorf("can't inject devices, nil OCI Spec")
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
c.refreshIfRequired(false)
|
||||||
|
|
||||||
|
edits := &ContainerEdits{}
|
||||||
|
specs := map[*Spec]struct{}{}
|
||||||
|
|
||||||
|
for _, device := range devices {
|
||||||
|
d := c.devices[device]
|
||||||
|
if d == nil {
|
||||||
|
unresolved = append(unresolved, device)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := specs[d.GetSpec()]; !ok {
|
||||||
|
specs[d.GetSpec()] = struct{}{}
|
||||||
|
edits.Append(d.GetSpec().edits())
|
||||||
|
}
|
||||||
|
edits.Append(d.edits())
|
||||||
|
}
|
||||||
|
|
||||||
|
if unresolved != nil {
|
||||||
|
return unresolved, fmt.Errorf("unresolvable CDI devices %s",
|
||||||
|
strings.Join(devices, ", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := edits.Apply(ociSpec); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to inject devices: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// highestPrioritySpecDir returns the Spec directory with highest priority
|
||||||
|
// and its priority.
|
||||||
|
func (c *Cache) highestPrioritySpecDir() (string, int) {
|
||||||
|
if len(c.specDirs) == 0 {
|
||||||
|
return "", -1
|
||||||
|
}
|
||||||
|
|
||||||
|
prio := len(c.specDirs) - 1
|
||||||
|
dir := c.specDirs[prio]
|
||||||
|
|
||||||
|
return dir, prio
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteSpec writes a Spec file with the given content into the highest
|
||||||
|
// priority Spec directory. If name has a "json" or "yaml" extension it
|
||||||
|
// choses the encoding. Otherwise the default YAML encoding is used.
|
||||||
|
func (c *Cache) WriteSpec(raw *cdi.Spec, name string) error {
|
||||||
|
var (
|
||||||
|
specDir string
|
||||||
|
path string
|
||||||
|
prio int
|
||||||
|
spec *Spec
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
specDir, prio = c.highestPrioritySpecDir()
|
||||||
|
if specDir == "" {
|
||||||
|
return errors.New("no Spec directories to write to")
|
||||||
|
}
|
||||||
|
|
||||||
|
path = filepath.Join(specDir, name)
|
||||||
|
if ext := filepath.Ext(path); ext != ".json" && ext != ".yaml" {
|
||||||
|
path += defaultSpecExt
|
||||||
|
}
|
||||||
|
|
||||||
|
spec, err = newSpec(raw, path, prio)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return spec.write(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveSpec removes a Spec with the given name from the highest
|
||||||
|
// priority Spec directory. This function can be used to remove a
|
||||||
|
// Spec previously written by WriteSpec(). If the file exists and
|
||||||
|
// its removal fails RemoveSpec returns an error.
|
||||||
|
func (c *Cache) RemoveSpec(name string) error {
|
||||||
|
var (
|
||||||
|
specDir string
|
||||||
|
path string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
specDir, _ = c.highestPrioritySpecDir()
|
||||||
|
if specDir == "" {
|
||||||
|
return errors.New("no Spec directories to remove from")
|
||||||
|
}
|
||||||
|
|
||||||
|
path = filepath.Join(specDir, name)
|
||||||
|
if ext := filepath.Ext(path); ext != ".json" && ext != ".yaml" {
|
||||||
|
path += defaultSpecExt
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Remove(path)
|
||||||
|
if err != nil && errors.Is(err, fs.ErrNotExist) {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDevice returns the cached device for the given qualified name.
|
||||||
|
func (c *Cache) GetDevice(device string) *Device {
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
c.refreshIfRequired(false)
|
||||||
|
|
||||||
|
return c.devices[device]
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListDevices lists all cached devices by qualified name.
|
||||||
|
func (c *Cache) ListDevices() []string {
|
||||||
|
var devices []string
|
||||||
|
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
c.refreshIfRequired(false)
|
||||||
|
|
||||||
|
for name := range c.devices {
|
||||||
|
devices = append(devices, name)
|
||||||
|
}
|
||||||
|
sort.Strings(devices)
|
||||||
|
|
||||||
|
return devices
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListVendors lists all vendors known to the cache.
|
||||||
|
func (c *Cache) ListVendors() []string {
|
||||||
|
var vendors []string
|
||||||
|
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
c.refreshIfRequired(false)
|
||||||
|
|
||||||
|
for vendor := range c.specs {
|
||||||
|
vendors = append(vendors, vendor)
|
||||||
|
}
|
||||||
|
sort.Strings(vendors)
|
||||||
|
|
||||||
|
return vendors
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListClasses lists all device classes known to the cache.
|
||||||
|
func (c *Cache) ListClasses() []string {
|
||||||
|
var (
|
||||||
|
cmap = map[string]struct{}{}
|
||||||
|
classes []string
|
||||||
|
)
|
||||||
|
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
c.refreshIfRequired(false)
|
||||||
|
|
||||||
|
for _, specs := range c.specs {
|
||||||
|
for _, spec := range specs {
|
||||||
|
cmap[spec.GetClass()] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for class := range cmap {
|
||||||
|
classes = append(classes, class)
|
||||||
|
}
|
||||||
|
sort.Strings(classes)
|
||||||
|
|
||||||
|
return classes
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVendorSpecs returns all specs for the given vendor.
|
||||||
|
func (c *Cache) GetVendorSpecs(vendor string) []*Spec {
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
c.refreshIfRequired(false)
|
||||||
|
|
||||||
|
return c.specs[vendor]
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSpecErrors returns all errors encountered for the spec during the
|
||||||
|
// last cache refresh.
|
||||||
|
func (c *Cache) GetSpecErrors(spec *Spec) []error {
|
||||||
|
var errors []error
|
||||||
|
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
if errs, ok := c.errors[spec.GetPath()]; ok {
|
||||||
|
errors = make([]error, len(errs))
|
||||||
|
copy(errors, errs)
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetErrors returns all errors encountered during the last
|
||||||
|
// cache refresh.
|
||||||
|
func (c *Cache) GetErrors() map[string][]error {
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
errors := map[string][]error{}
|
||||||
|
for path, errs := range c.errors {
|
||||||
|
errors[path] = errs
|
||||||
|
}
|
||||||
|
for path, err := range c.dirErrors {
|
||||||
|
errors[path] = []error{err}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSpecDirectories returns the CDI Spec directories currently in use.
|
||||||
|
func (c *Cache) GetSpecDirectories() []string {
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
dirs := make([]string, len(c.specDirs))
|
||||||
|
copy(dirs, c.specDirs)
|
||||||
|
return dirs
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSpecDirErrors returns any errors related to configured Spec directories.
|
||||||
|
func (c *Cache) GetSpecDirErrors() map[string]error {
|
||||||
|
if c.dirErrors == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
errors := make(map[string]error)
|
||||||
|
for dir, err := range c.dirErrors {
|
||||||
|
errors[dir] = err
|
||||||
|
}
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our fsnotify helper wrapper.
|
||||||
|
type watch struct {
|
||||||
|
watcher *fsnotify.Watcher
|
||||||
|
tracked map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup monitoring for the given Spec directories.
|
||||||
|
func (w *watch) setup(dirs []string, dirErrors map[string]error) {
|
||||||
|
var (
|
||||||
|
dir string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
w.tracked = make(map[string]bool)
|
||||||
|
for _, dir = range dirs {
|
||||||
|
w.tracked[dir] = false
|
||||||
|
}
|
||||||
|
|
||||||
|
w.watcher, err = fsnotify.NewWatcher()
|
||||||
|
if err != nil {
|
||||||
|
for _, dir := range dirs {
|
||||||
|
dirErrors[dir] = fmt.Errorf("failed to create watcher: %w", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.update(dirErrors)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start watching Spec directories for relevant changes.
|
||||||
|
func (w *watch) start(m *sync.Mutex, refresh func() error, dirErrors map[string]error) {
|
||||||
|
go w.watch(w.watcher, m, refresh, dirErrors)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop watching directories.
|
||||||
|
func (w *watch) stop() {
|
||||||
|
if w.watcher == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.watcher.Close()
|
||||||
|
w.tracked = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch Spec directory changes, triggering a refresh if necessary.
|
||||||
|
func (w *watch) watch(fsw *fsnotify.Watcher, m *sync.Mutex, refresh func() error, dirErrors map[string]error) {
|
||||||
|
watch := fsw
|
||||||
|
if watch == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case event, ok := <-watch.Events:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.Op & (fsnotify.Rename | fsnotify.Remove | fsnotify.Write)) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if event.Op == fsnotify.Write {
|
||||||
|
if ext := filepath.Ext(event.Name); ext != ".json" && ext != ".yaml" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Lock()
|
||||||
|
if event.Op == fsnotify.Remove && w.tracked[event.Name] {
|
||||||
|
w.update(dirErrors, event.Name)
|
||||||
|
} else {
|
||||||
|
w.update(dirErrors)
|
||||||
|
}
|
||||||
|
refresh()
|
||||||
|
m.Unlock()
|
||||||
|
|
||||||
|
case _, ok := <-watch.Errors:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update watch with pending/missing or removed directories.
|
||||||
|
func (w *watch) update(dirErrors map[string]error, removed ...string) bool {
|
||||||
|
var (
|
||||||
|
dir string
|
||||||
|
ok bool
|
||||||
|
err error
|
||||||
|
update bool
|
||||||
|
)
|
||||||
|
|
||||||
|
for dir, ok = range w.tracked {
|
||||||
|
if ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = w.watcher.Add(dir)
|
||||||
|
if err == nil {
|
||||||
|
w.tracked[dir] = true
|
||||||
|
delete(dirErrors, dir)
|
||||||
|
update = true
|
||||||
|
} else {
|
||||||
|
w.tracked[dir] = false
|
||||||
|
dirErrors[dir] = fmt.Errorf("failed to monitor for changes: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, dir = range removed {
|
||||||
|
w.tracked[dir] = false
|
||||||
|
dirErrors[dir] = errors.New("directory removed")
|
||||||
|
update = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return update
|
||||||
|
}
|
26
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_unix.go
generated
vendored
Normal file
26
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_unix.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//go:build !windows
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
func osSync() {
|
||||||
|
syscall.Sync()
|
||||||
|
}
|
22
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_windows.go
generated
vendored
Normal file
22
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_windows.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
func osSync() {}
|
332
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits.go
generated
vendored
Normal file
332
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits.go
generated
vendored
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
|
oci "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
ocigen "github.com/opencontainers/runtime-tools/generate"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// PrestartHook is the name of the OCI "prestart" hook.
|
||||||
|
PrestartHook = "prestart"
|
||||||
|
// CreateRuntimeHook is the name of the OCI "createRuntime" hook.
|
||||||
|
CreateRuntimeHook = "createRuntime"
|
||||||
|
// CreateContainerHook is the name of the OCI "createContainer" hook.
|
||||||
|
CreateContainerHook = "createContainer"
|
||||||
|
// StartContainerHook is the name of the OCI "startContainer" hook.
|
||||||
|
StartContainerHook = "startContainer"
|
||||||
|
// PoststartHook is the name of the OCI "poststart" hook.
|
||||||
|
PoststartHook = "poststart"
|
||||||
|
// PoststopHook is the name of the OCI "poststop" hook.
|
||||||
|
PoststopHook = "poststop"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Names of recognized hooks.
|
||||||
|
validHookNames = map[string]struct{}{
|
||||||
|
PrestartHook: {},
|
||||||
|
CreateRuntimeHook: {},
|
||||||
|
CreateContainerHook: {},
|
||||||
|
StartContainerHook: {},
|
||||||
|
PoststartHook: {},
|
||||||
|
PoststopHook: {},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// ContainerEdits represent updates to be applied to an OCI Spec.
|
||||||
|
// These updates can be specific to a CDI device, or they can be
|
||||||
|
// specific to a CDI Spec. In the former case these edits should
|
||||||
|
// be applied to all OCI Specs where the corresponding CDI device
|
||||||
|
// is injected. In the latter case, these edits should be applied
|
||||||
|
// to all OCI Specs where at least one devices from the CDI Spec
|
||||||
|
// is injected.
|
||||||
|
type ContainerEdits struct {
|
||||||
|
*specs.ContainerEdits
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply edits to the given OCI Spec. Updates the OCI Spec in place.
|
||||||
|
// Returns an error if the update fails.
|
||||||
|
func (e *ContainerEdits) Apply(spec *oci.Spec) error {
|
||||||
|
if spec == nil {
|
||||||
|
return errors.New("can't edit nil OCI Spec")
|
||||||
|
}
|
||||||
|
if e == nil || e.ContainerEdits == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
specgen := ocigen.NewFromSpec(spec)
|
||||||
|
if len(e.Env) > 0 {
|
||||||
|
specgen.AddMultipleProcessEnv(e.Env)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, d := range e.DeviceNodes {
|
||||||
|
dn := DeviceNode{d}
|
||||||
|
|
||||||
|
err := dn.fillMissingInfo()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dev := d.ToOCI()
|
||||||
|
if dev.UID == nil && spec.Process != nil {
|
||||||
|
if uid := spec.Process.User.UID; uid > 0 {
|
||||||
|
dev.UID = &uid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if dev.GID == nil && spec.Process != nil {
|
||||||
|
if gid := spec.Process.User.GID; gid > 0 {
|
||||||
|
dev.GID = &gid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
specgen.RemoveDevice(dev.Path)
|
||||||
|
specgen.AddDevice(dev)
|
||||||
|
|
||||||
|
if dev.Type == "b" || dev.Type == "c" {
|
||||||
|
access := d.Permissions
|
||||||
|
if access == "" {
|
||||||
|
access = "rwm"
|
||||||
|
}
|
||||||
|
specgen.AddLinuxResourcesDevice(true, dev.Type, &dev.Major, &dev.Minor, access)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(e.Mounts) > 0 {
|
||||||
|
for _, m := range e.Mounts {
|
||||||
|
specgen.RemoveMount(m.ContainerPath)
|
||||||
|
specgen.AddMount(m.ToOCI())
|
||||||
|
}
|
||||||
|
sortMounts(&specgen)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, h := range e.Hooks {
|
||||||
|
switch h.HookName {
|
||||||
|
case PrestartHook:
|
||||||
|
specgen.AddPreStartHook(h.ToOCI())
|
||||||
|
case PoststartHook:
|
||||||
|
specgen.AddPostStartHook(h.ToOCI())
|
||||||
|
case PoststopHook:
|
||||||
|
specgen.AddPostStopHook(h.ToOCI())
|
||||||
|
// TODO: Maybe runtime-tools/generate should be updated with these...
|
||||||
|
case CreateRuntimeHook:
|
||||||
|
ensureOCIHooks(spec)
|
||||||
|
spec.Hooks.CreateRuntime = append(spec.Hooks.CreateRuntime, h.ToOCI())
|
||||||
|
case CreateContainerHook:
|
||||||
|
ensureOCIHooks(spec)
|
||||||
|
spec.Hooks.CreateContainer = append(spec.Hooks.CreateContainer, h.ToOCI())
|
||||||
|
case StartContainerHook:
|
||||||
|
ensureOCIHooks(spec)
|
||||||
|
spec.Hooks.StartContainer = append(spec.Hooks.StartContainer, h.ToOCI())
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown hook name %q", h.HookName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate container edits.
|
||||||
|
func (e *ContainerEdits) Validate() error {
|
||||||
|
if e == nil || e.ContainerEdits == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateEnv(e.Env); err != nil {
|
||||||
|
return fmt.Errorf("invalid container edits: %w", err)
|
||||||
|
}
|
||||||
|
for _, d := range e.DeviceNodes {
|
||||||
|
if err := (&DeviceNode{d}).Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, h := range e.Hooks {
|
||||||
|
if err := (&Hook{h}).Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, m := range e.Mounts {
|
||||||
|
if err := (&Mount{m}).Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append other edits into this one. If called with a nil receiver,
|
||||||
|
// allocates and returns newly allocated edits.
|
||||||
|
func (e *ContainerEdits) Append(o *ContainerEdits) *ContainerEdits {
|
||||||
|
if o == nil || o.ContainerEdits == nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
if e == nil {
|
||||||
|
e = &ContainerEdits{}
|
||||||
|
}
|
||||||
|
if e.ContainerEdits == nil {
|
||||||
|
e.ContainerEdits = &specs.ContainerEdits{}
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Env = append(e.Env, o.Env...)
|
||||||
|
e.DeviceNodes = append(e.DeviceNodes, o.DeviceNodes...)
|
||||||
|
e.Hooks = append(e.Hooks, o.Hooks...)
|
||||||
|
e.Mounts = append(e.Mounts, o.Mounts...)
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// isEmpty returns true if these edits are empty. This is valid in a
|
||||||
|
// global Spec context but invalid in a Device context.
|
||||||
|
func (e *ContainerEdits) isEmpty() bool {
|
||||||
|
if e == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return len(e.Env)+len(e.DeviceNodes)+len(e.Hooks)+len(e.Mounts) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateEnv validates the given environment variables.
|
||||||
|
func ValidateEnv(env []string) error {
|
||||||
|
for _, v := range env {
|
||||||
|
if strings.IndexByte(v, byte('=')) <= 0 {
|
||||||
|
return fmt.Errorf("invalid environment variable %q", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceNode is a CDI Spec DeviceNode wrapper, used for validating DeviceNodes.
|
||||||
|
type DeviceNode struct {
|
||||||
|
*specs.DeviceNode
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate a CDI Spec DeviceNode.
|
||||||
|
func (d *DeviceNode) Validate() error {
|
||||||
|
validTypes := map[string]struct{}{
|
||||||
|
"": {},
|
||||||
|
"b": {},
|
||||||
|
"c": {},
|
||||||
|
"u": {},
|
||||||
|
"p": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.Path == "" {
|
||||||
|
return errors.New("invalid (empty) device path")
|
||||||
|
}
|
||||||
|
if _, ok := validTypes[d.Type]; !ok {
|
||||||
|
return fmt.Errorf("device %q: invalid type %q", d.Path, d.Type)
|
||||||
|
}
|
||||||
|
for _, bit := range d.Permissions {
|
||||||
|
if bit != 'r' && bit != 'w' && bit != 'm' {
|
||||||
|
return fmt.Errorf("device %q: invalid permissions %q",
|
||||||
|
d.Path, d.Permissions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook is a CDI Spec Hook wrapper, used for validating hooks.
|
||||||
|
type Hook struct {
|
||||||
|
*specs.Hook
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate a hook.
|
||||||
|
func (h *Hook) Validate() error {
|
||||||
|
if _, ok := validHookNames[h.HookName]; !ok {
|
||||||
|
return fmt.Errorf("invalid hook name %q", h.HookName)
|
||||||
|
}
|
||||||
|
if h.Path == "" {
|
||||||
|
return fmt.Errorf("invalid hook %q with empty path", h.HookName)
|
||||||
|
}
|
||||||
|
if err := ValidateEnv(h.Env); err != nil {
|
||||||
|
return fmt.Errorf("invalid hook %q: %w", h.HookName, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mount is a CDI Mount wrapper, used for validating mounts.
|
||||||
|
type Mount struct {
|
||||||
|
*specs.Mount
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate a mount.
|
||||||
|
func (m *Mount) Validate() error {
|
||||||
|
if m.HostPath == "" {
|
||||||
|
return errors.New("invalid mount, empty host path")
|
||||||
|
}
|
||||||
|
if m.ContainerPath == "" {
|
||||||
|
return errors.New("invalid mount, empty container path")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure OCI Spec hooks are not nil so we can add hooks.
|
||||||
|
func ensureOCIHooks(spec *oci.Spec) {
|
||||||
|
if spec.Hooks == nil {
|
||||||
|
spec.Hooks = &oci.Hooks{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sortMounts sorts the mounts in the given OCI Spec.
|
||||||
|
func sortMounts(specgen *ocigen.Generator) {
|
||||||
|
mounts := specgen.Mounts()
|
||||||
|
specgen.ClearMounts()
|
||||||
|
sort.Sort(orderedMounts(mounts))
|
||||||
|
specgen.Config.Mounts = mounts
|
||||||
|
}
|
||||||
|
|
||||||
|
// orderedMounts defines how to sort an OCI Spec Mount slice.
|
||||||
|
// This is the almost the same implementation sa used by CRI-O and Docker,
|
||||||
|
// with a minor tweak for stable sorting order (easier to test):
|
||||||
|
//
|
||||||
|
// https://github.com/moby/moby/blob/17.05.x/daemon/volumes.go#L26
|
||||||
|
type orderedMounts []oci.Mount
|
||||||
|
|
||||||
|
// Len returns the number of mounts. Used in sorting.
|
||||||
|
func (m orderedMounts) Len() int {
|
||||||
|
return len(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Less returns true if the number of parts (a/b/c would be 3 parts) in the
|
||||||
|
// mount indexed by parameter 1 is less than that of the mount indexed by
|
||||||
|
// parameter 2. Used in sorting.
|
||||||
|
func (m orderedMounts) Less(i, j int) bool {
|
||||||
|
ip, jp := m.parts(i), m.parts(j)
|
||||||
|
if ip < jp {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if jp < ip {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return m[i].Destination < m[j].Destination
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap swaps two items in an array of mounts. Used in sorting
|
||||||
|
func (m orderedMounts) Swap(i, j int) {
|
||||||
|
m[i], m[j] = m[j], m[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// parts returns the number of parts in the destination of a mount. Used in sorting.
|
||||||
|
func (m orderedMounts) parts(i int) int {
|
||||||
|
return strings.Count(filepath.Clean(m[i].Destination), string(os.PathSeparator))
|
||||||
|
}
|
57
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_unix.go
generated
vendored
Normal file
57
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_unix.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
//go:build !windows
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
runc "github.com/opencontainers/runc/libcontainer/devices"
|
||||||
|
)
|
||||||
|
|
||||||
|
// fillMissingInfo fills in missing mandatory attributes from the host device.
|
||||||
|
func (d *DeviceNode) fillMissingInfo() error {
|
||||||
|
if d.HostPath == "" {
|
||||||
|
d.HostPath = d.Path
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.Type != "" && (d.Major != 0 || d.Type == "p") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
hostDev, err := runc.DeviceFromPath(d.HostPath, "rwm")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to stat CDI host device %q: %w", d.HostPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.Type == "" {
|
||||||
|
d.Type = string(hostDev.Type)
|
||||||
|
} else {
|
||||||
|
if d.Type != string(hostDev.Type) {
|
||||||
|
return fmt.Errorf("CDI device (%q, %q), host type mismatch (%s, %s)",
|
||||||
|
d.Path, d.HostPath, d.Type, string(hostDev.Type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if d.Major == 0 && d.Type != "p" {
|
||||||
|
d.Major = hostDev.Major
|
||||||
|
d.Minor = hostDev.Minor
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
27
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_windows.go
generated
vendored
Normal file
27
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_windows.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// fillMissingInfo fills in missing mandatory attributes from the host device.
|
||||||
|
func (d *DeviceNode) fillMissingInfo() error {
|
||||||
|
return fmt.Errorf("unimplemented")
|
||||||
|
}
|
88
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/device.go
generated
vendored
Normal file
88
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/device.go
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/container-orchestrated-devices/container-device-interface/internal/validation"
|
||||||
|
"github.com/container-orchestrated-devices/container-device-interface/pkg/parser"
|
||||||
|
cdi "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
|
oci "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Device represents a CDI device of a Spec.
|
||||||
|
type Device struct {
|
||||||
|
*cdi.Device
|
||||||
|
spec *Spec
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new Device, associate it with the given Spec.
|
||||||
|
func newDevice(spec *Spec, d cdi.Device) (*Device, error) {
|
||||||
|
dev := &Device{
|
||||||
|
Device: &d,
|
||||||
|
spec: spec,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dev.validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return dev, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSpec returns the Spec this device is defined in.
|
||||||
|
func (d *Device) GetSpec() *Spec {
|
||||||
|
return d.spec
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetQualifiedName returns the qualified name for this device.
|
||||||
|
func (d *Device) GetQualifiedName() string {
|
||||||
|
return parser.QualifiedName(d.spec.GetVendor(), d.spec.GetClass(), d.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApplyEdits applies the device-speific container edits to an OCI Spec.
|
||||||
|
func (d *Device) ApplyEdits(ociSpec *oci.Spec) error {
|
||||||
|
return d.edits().Apply(ociSpec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// edits returns the applicable container edits for this spec.
|
||||||
|
func (d *Device) edits() *ContainerEdits {
|
||||||
|
return &ContainerEdits{&d.ContainerEdits}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the device.
|
||||||
|
func (d *Device) validate() error {
|
||||||
|
if err := ValidateDeviceName(d.Name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
name := d.Name
|
||||||
|
if d.spec != nil {
|
||||||
|
name = d.GetQualifiedName()
|
||||||
|
}
|
||||||
|
if err := validation.ValidateSpecAnnotations(name, d.Annotations); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
edits := d.edits()
|
||||||
|
if edits.isEmpty() {
|
||||||
|
return fmt.Errorf("invalid device, empty device edits")
|
||||||
|
}
|
||||||
|
if err := edits.Validate(); err != nil {
|
||||||
|
return fmt.Errorf("invalid device %q: %w", d.Name, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
272
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/doc.go
generated
vendored
Normal file
272
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/doc.go
generated
vendored
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
// Package cdi has the primary purpose of providing an API for
|
||||||
|
// interacting with CDI and consuming CDI devices.
|
||||||
|
//
|
||||||
|
// For more information about Container Device Interface, please refer to
|
||||||
|
// https://github.com/container-orchestrated-devices/container-device-interface
|
||||||
|
//
|
||||||
|
// Container Device Interface
|
||||||
|
//
|
||||||
|
// Container Device Interface, or CDI for short, provides comprehensive
|
||||||
|
// third party device support for container runtimes. CDI uses vendor
|
||||||
|
// provided specification files, CDI Specs for short, to describe how a
|
||||||
|
// container's runtime environment should be modified when one or more
|
||||||
|
// of the vendor-specific devices is injected into the container. Beyond
|
||||||
|
// describing the low level platform-specific details of how to gain
|
||||||
|
// basic access to a device, CDI Specs allow more fine-grained device
|
||||||
|
// initialization, and the automatic injection of any necessary vendor-
|
||||||
|
// or device-specific software that might be required for a container
|
||||||
|
// to use a device or take full advantage of it.
|
||||||
|
//
|
||||||
|
// In the CDI device model containers request access to a device using
|
||||||
|
// fully qualified device names, qualified names for short, consisting of
|
||||||
|
// a vendor identifier, a device class and a device name or identifier.
|
||||||
|
// These pieces of information together uniquely identify a device among
|
||||||
|
// all device vendors, classes and device instances.
|
||||||
|
//
|
||||||
|
// This package implements an API for easy consumption of CDI. The API
|
||||||
|
// implements discovery, loading and caching of CDI Specs and injection
|
||||||
|
// of CDI devices into containers. This is the most common functionality
|
||||||
|
// the vast majority of CDI consumers need. The API should be usable both
|
||||||
|
// by OCI runtime clients and runtime implementations.
|
||||||
|
//
|
||||||
|
// CDI Registry
|
||||||
|
//
|
||||||
|
// The primary interface to interact with CDI devices is the Registry. It
|
||||||
|
// is essentially a cache of all Specs and devices discovered in standard
|
||||||
|
// CDI directories on the host. The registry has two main functionality,
|
||||||
|
// injecting devices into an OCI Spec and refreshing the cache of CDI
|
||||||
|
// Specs and devices.
|
||||||
|
//
|
||||||
|
// Device Injection
|
||||||
|
//
|
||||||
|
// Using the Registry one can inject CDI devices into a container with code
|
||||||
|
// similar to the following snippet:
|
||||||
|
//
|
||||||
|
// import (
|
||||||
|
// "fmt"
|
||||||
|
// "strings"
|
||||||
|
//
|
||||||
|
// log "github.com/sirupsen/logrus"
|
||||||
|
//
|
||||||
|
// "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
||||||
|
// oci "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// func injectCDIDevices(spec *oci.Spec, devices []string) error {
|
||||||
|
// log.Debug("pristine OCI Spec: %s", dumpSpec(spec))
|
||||||
|
//
|
||||||
|
// unresolved, err := cdi.GetRegistry().InjectDevices(spec, devices)
|
||||||
|
// if err != nil {
|
||||||
|
// return fmt.Errorf("CDI device injection failed: %w", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// log.Debug("CDI-updated OCI Spec: %s", dumpSpec(spec))
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Cache Refresh
|
||||||
|
//
|
||||||
|
// By default the CDI Spec cache monitors the configured Spec directories
|
||||||
|
// and automatically refreshes itself when necessary. This behavior can be
|
||||||
|
// disabled using the WithAutoRefresh(false) option.
|
||||||
|
//
|
||||||
|
// Failure to set up monitoring for a Spec directory causes the directory to
|
||||||
|
// get ignored and an error to be recorded among the Spec directory errors.
|
||||||
|
// These errors can be queried using the GetSpecDirErrors() function. If the
|
||||||
|
// error condition is transient, for instance a missing directory which later
|
||||||
|
// gets created, the corresponding error will be removed once the condition
|
||||||
|
// is over.
|
||||||
|
//
|
||||||
|
// With auto-refresh enabled injecting any CDI devices can be done without
|
||||||
|
// an explicit call to Refresh(), using a code snippet similar to the
|
||||||
|
// following:
|
||||||
|
//
|
||||||
|
// In a runtime implementation one typically wants to make sure the
|
||||||
|
// CDI Spec cache is up to date before performing device injection.
|
||||||
|
// A code snippet similar to the following accmplishes that:
|
||||||
|
//
|
||||||
|
// import (
|
||||||
|
// "fmt"
|
||||||
|
// "strings"
|
||||||
|
//
|
||||||
|
// log "github.com/sirupsen/logrus"
|
||||||
|
//
|
||||||
|
// "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
||||||
|
// oci "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// func injectCDIDevices(spec *oci.Spec, devices []string) error {
|
||||||
|
// registry := cdi.GetRegistry()
|
||||||
|
//
|
||||||
|
// if err := registry.Refresh(); err != nil {
|
||||||
|
// // Note:
|
||||||
|
// // It is up to the implementation to decide whether
|
||||||
|
// // to abort injection on errors. A failed Refresh()
|
||||||
|
// // does not necessarily render the registry unusable.
|
||||||
|
// // For instance, a parse error in a Spec file for
|
||||||
|
// // vendor A does not have any effect on devices of
|
||||||
|
// // vendor B...
|
||||||
|
// log.Warnf("pre-injection Refresh() failed: %v", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// log.Debug("pristine OCI Spec: %s", dumpSpec(spec))
|
||||||
|
//
|
||||||
|
// unresolved, err := registry.InjectDevices(spec, devices)
|
||||||
|
// if err != nil {
|
||||||
|
// return fmt.Errorf("CDI device injection failed: %w", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// log.Debug("CDI-updated OCI Spec: %s", dumpSpec(spec))
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Generated Spec Files, Multiple Directories, Device Precedence
|
||||||
|
//
|
||||||
|
// It is often necessary to generate Spec files dynamically. On some
|
||||||
|
// systems the available or usable set of CDI devices might change
|
||||||
|
// dynamically which then needs to be reflected in CDI Specs. For
|
||||||
|
// some device classes it makes sense to enumerate the available
|
||||||
|
// devices at every boot and generate Spec file entries for each
|
||||||
|
// device found. Some CDI devices might need special client- or
|
||||||
|
// request-specific configuration which can only be fulfilled by
|
||||||
|
// dynamically generated client-specific entries in transient Spec
|
||||||
|
// files.
|
||||||
|
//
|
||||||
|
// CDI can collect Spec files from multiple directories. Spec files are
|
||||||
|
// automatically assigned priorities according to which directory they
|
||||||
|
// were loaded from. The later a directory occurs in the list of CDI
|
||||||
|
// directories to scan, the higher priority Spec files loaded from that
|
||||||
|
// directory are assigned to. When two or more Spec files define the
|
||||||
|
// same device, conflict is resolved by choosing the definition from the
|
||||||
|
// Spec file with the highest priority.
|
||||||
|
//
|
||||||
|
// The default CDI directory configuration is chosen to encourage
|
||||||
|
// separating dynamically generated CDI Spec files from static ones.
|
||||||
|
// The default directories are '/etc/cdi' and '/var/run/cdi'. By putting
|
||||||
|
// dynamically generated Spec files under '/var/run/cdi', those take
|
||||||
|
// precedence over static ones in '/etc/cdi'. With this scheme, static
|
||||||
|
// Spec files, typically installed by distro-specific packages, go into
|
||||||
|
// '/etc/cdi' while all the dynamically generated Spec files, transient
|
||||||
|
// or other, go into '/var/run/cdi'.
|
||||||
|
//
|
||||||
|
// Spec File Generation
|
||||||
|
//
|
||||||
|
// CDI offers two functions for writing and removing dynamically generated
|
||||||
|
// Specs from CDI Spec directories. These functions, WriteSpec() and
|
||||||
|
// RemoveSpec() implicitly follow the principle of separating dynamic Specs
|
||||||
|
// from the rest and therefore always write to and remove Specs from the
|
||||||
|
// last configured directory.
|
||||||
|
//
|
||||||
|
// Corresponding functions are also provided for generating names for Spec
|
||||||
|
// files. These functions follow a simple naming convention to ensure that
|
||||||
|
// multiple entities generating Spec files simultaneously on the same host
|
||||||
|
// do not end up using conflicting Spec file names. GenerateSpecName(),
|
||||||
|
// GenerateNameForSpec(), GenerateTransientSpecName(), and
|
||||||
|
// GenerateTransientNameForSpec() all generate names which can be passed
|
||||||
|
// as such to WriteSpec() and subsequently to RemoveSpec().
|
||||||
|
//
|
||||||
|
// Generating a Spec file for a vendor/device class can be done with a
|
||||||
|
// code snippet similar to the following:
|
||||||
|
//
|
||||||
|
// import (
|
||||||
|
// "fmt"
|
||||||
|
// ...
|
||||||
|
// "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
|
// "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// func generateDeviceSpecs() error {
|
||||||
|
// registry := cdi.GetRegistry()
|
||||||
|
// spec := &specs.Spec{
|
||||||
|
// Version: specs.CurrentVersion,
|
||||||
|
// Kind: vendor+"/"+class,
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for _, dev := range enumerateDevices() {
|
||||||
|
// spec.Devices = append(spec.Devices, specs.Device{
|
||||||
|
// Name: dev.Name,
|
||||||
|
// ContainerEdits: getContainerEditsForDevice(dev),
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// specName, err := cdi.GenerateNameForSpec(spec)
|
||||||
|
// if err != nil {
|
||||||
|
// return fmt.Errorf("failed to generate Spec name: %w", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return registry.SpecDB().WriteSpec(spec, specName)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Similarly, generating and later cleaning up transient Spec files can be
|
||||||
|
// done with code fragments similar to the following. These transient Spec
|
||||||
|
// files are temporary Spec files with container-specific parametrization.
|
||||||
|
// They are typically created before the associated container is created
|
||||||
|
// and removed once that container is removed.
|
||||||
|
//
|
||||||
|
// import (
|
||||||
|
// "fmt"
|
||||||
|
// ...
|
||||||
|
// "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
|
// "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// func generateTransientSpec(ctr Container) error {
|
||||||
|
// registry := cdi.GetRegistry()
|
||||||
|
// devices := getContainerDevs(ctr, vendor, class)
|
||||||
|
// spec := &specs.Spec{
|
||||||
|
// Version: specs.CurrentVersion,
|
||||||
|
// Kind: vendor+"/"+class,
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for _, dev := range devices {
|
||||||
|
// spec.Devices = append(spec.Devices, specs.Device{
|
||||||
|
// // the generated name needs to be unique within the
|
||||||
|
// // vendor/class domain on the host/node.
|
||||||
|
// Name: generateUniqueDevName(dev, ctr),
|
||||||
|
// ContainerEdits: getEditsForContainer(dev),
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // transientID is expected to guarantee that the Spec file name
|
||||||
|
// // generated using <vendor, class, transientID> is unique within
|
||||||
|
// // the host/node. If more than one device is allocated with the
|
||||||
|
// // same vendor/class domain, either all generated Spec entries
|
||||||
|
// // should go to a single Spec file (like in this sample snippet),
|
||||||
|
// // or transientID should be unique for each generated Spec file.
|
||||||
|
// transientID := getSomeSufficientlyUniqueIDForContainer(ctr)
|
||||||
|
// specName, err := cdi.GenerateNameForTransientSpec(vendor, class, transientID)
|
||||||
|
// if err != nil {
|
||||||
|
// return fmt.Errorf("failed to generate Spec name: %w", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return registry.SpecDB().WriteSpec(spec, specName)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func removeTransientSpec(ctr Container) error {
|
||||||
|
// registry := cdi.GetRegistry()
|
||||||
|
// transientID := getSomeSufficientlyUniqueIDForContainer(ctr)
|
||||||
|
// specName := cdi.GenerateNameForTransientSpec(vendor, class, transientID)
|
||||||
|
//
|
||||||
|
// return registry.SpecDB().RemoveSpec(specName)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// CDI Spec Validation
|
||||||
|
//
|
||||||
|
// This package performs both syntactic and semantic validation of CDI
|
||||||
|
// Spec file data when a Spec file is loaded via the registry or using
|
||||||
|
// the ReadSpec API function. As part of the semantic verification, the
|
||||||
|
// Spec file is verified against the CDI Spec JSON validation schema.
|
||||||
|
//
|
||||||
|
// If a valid externally provided JSON validation schema is found in
|
||||||
|
// the filesystem at /etc/cdi/schema/schema.json it is loaded and used
|
||||||
|
// as the default validation schema. If such a file is not found or
|
||||||
|
// fails to load, an embedded no-op schema is used.
|
||||||
|
//
|
||||||
|
// The used validation schema can also be changed programmatically using
|
||||||
|
// the SetSchema API convenience function. This function also accepts
|
||||||
|
// the special "builtin" (BuiltinSchemaName) and "none" (NoneSchemaName)
|
||||||
|
// schema names which switch the used schema to the in-repo validation
|
||||||
|
// schema embedded into the binary or the now default no-op schema
|
||||||
|
// correspondingly. Other names are interpreted as the path to the actual
|
||||||
|
// validation schema to load and use.
|
||||||
|
package cdi
|
113
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/qualified-device.go
generated
vendored
Normal file
113
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/qualified-device.go
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/container-orchestrated-devices/container-device-interface/pkg/parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
// QualifiedName returns the qualified name for a device.
|
||||||
|
// The syntax for a qualified device names is
|
||||||
|
//
|
||||||
|
// "<vendor>/<class>=<name>".
|
||||||
|
//
|
||||||
|
// A valid vendor and class name may contain the following runes:
|
||||||
|
//
|
||||||
|
// 'A'-'Z', 'a'-'z', '0'-'9', '.', '-', '_'.
|
||||||
|
//
|
||||||
|
// A valid device name may contain the following runes:
|
||||||
|
//
|
||||||
|
// 'A'-'Z', 'a'-'z', '0'-'9', '-', '_', '.', ':'
|
||||||
|
//
|
||||||
|
// Deprecated: use parser.QualifiedName instead
|
||||||
|
func QualifiedName(vendor, class, name string) string {
|
||||||
|
return parser.QualifiedName(vendor, class, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsQualifiedName tests if a device name is qualified.
|
||||||
|
//
|
||||||
|
// Deprecated: use parser.IsQualifiedName instead
|
||||||
|
func IsQualifiedName(device string) bool {
|
||||||
|
return parser.IsQualifiedName(device)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseQualifiedName splits a qualified name into device vendor, class,
|
||||||
|
// and name. If the device fails to parse as a qualified name, or if any
|
||||||
|
// of the split components fail to pass syntax validation, vendor and
|
||||||
|
// class are returned as empty, together with the verbatim input as the
|
||||||
|
// name and an error describing the reason for failure.
|
||||||
|
//
|
||||||
|
// Deprecated: use parser.ParseQualifiedName instead
|
||||||
|
func ParseQualifiedName(device string) (string, string, string, error) {
|
||||||
|
return parser.ParseQualifiedName(device)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDevice tries to split a device name into vendor, class, and name.
|
||||||
|
// If this fails, for instance in the case of unqualified device names,
|
||||||
|
// ParseDevice returns an empty vendor and class together with name set
|
||||||
|
// to the verbatim input.
|
||||||
|
//
|
||||||
|
// Deprecated: use parser.ParseDevice instead
|
||||||
|
func ParseDevice(device string) (string, string, string) {
|
||||||
|
return parser.ParseDevice(device)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseQualifier splits a device qualifier into vendor and class.
|
||||||
|
// The syntax for a device qualifier is
|
||||||
|
//
|
||||||
|
// "<vendor>/<class>"
|
||||||
|
//
|
||||||
|
// If parsing fails, an empty vendor and the class set to the
|
||||||
|
// verbatim input is returned.
|
||||||
|
//
|
||||||
|
// Deprecated: use parser.ParseQualifier instead
|
||||||
|
func ParseQualifier(kind string) (string, string) {
|
||||||
|
return parser.ParseQualifier(kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateVendorName checks the validity of a vendor name.
|
||||||
|
// A vendor name may contain the following ASCII characters:
|
||||||
|
// - upper- and lowercase letters ('A'-'Z', 'a'-'z')
|
||||||
|
// - digits ('0'-'9')
|
||||||
|
// - underscore, dash, and dot ('_', '-', and '.')
|
||||||
|
//
|
||||||
|
// Deprecated: use parser.ValidateVendorName instead
|
||||||
|
func ValidateVendorName(vendor string) error {
|
||||||
|
return parser.ValidateVendorName(vendor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateClassName checks the validity of class name.
|
||||||
|
// A class name may contain the following ASCII characters:
|
||||||
|
// - upper- and lowercase letters ('A'-'Z', 'a'-'z')
|
||||||
|
// - digits ('0'-'9')
|
||||||
|
// - underscore, dash, and dot ('_', '-', and '.')
|
||||||
|
//
|
||||||
|
// Deprecated: use parser.ValidateClassName instead
|
||||||
|
func ValidateClassName(class string) error {
|
||||||
|
return parser.ValidateClassName(class)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateDeviceName checks the validity of a device name.
|
||||||
|
// A device name may contain the following ASCII characters:
|
||||||
|
// - upper- and lowercase letters ('A'-'Z', 'a'-'z')
|
||||||
|
// - digits ('0'-'9')
|
||||||
|
// - underscore, dash, dot, colon ('_', '-', '.', ':')
|
||||||
|
//
|
||||||
|
// Deprecated: use parser.ValidateDeviceName instead
|
||||||
|
func ValidateDeviceName(name string) error {
|
||||||
|
return parser.ValidateDeviceName(name)
|
||||||
|
}
|
150
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/registry.go
generated
vendored
Normal file
150
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/registry.go
generated
vendored
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
cdi "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
|
oci "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Registry keeps a cache of all CDI Specs installed or generated on
|
||||||
|
// the host. Registry is the primary interface clients should use to
|
||||||
|
// interact with CDI.
|
||||||
|
//
|
||||||
|
// The most commonly used Registry functions are for refreshing the
|
||||||
|
// registry and injecting CDI devices into an OCI Spec.
|
||||||
|
type Registry interface {
|
||||||
|
RegistryResolver
|
||||||
|
RegistryRefresher
|
||||||
|
DeviceDB() RegistryDeviceDB
|
||||||
|
SpecDB() RegistrySpecDB
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegistryRefresher is the registry interface for refreshing the
|
||||||
|
// cache of CDI Specs and devices.
|
||||||
|
//
|
||||||
|
// Configure reconfigures the registry with the given options.
|
||||||
|
//
|
||||||
|
// Refresh rescans all CDI Spec directories and updates the
|
||||||
|
// state of the cache to reflect any changes. It returns any
|
||||||
|
// errors encountered during the refresh.
|
||||||
|
//
|
||||||
|
// GetErrors returns all errors encountered for any of the scanned
|
||||||
|
// Spec files during the last cache refresh.
|
||||||
|
//
|
||||||
|
// GetSpecDirectories returns the set up CDI Spec directories
|
||||||
|
// currently in use. The directories are returned in the scan
|
||||||
|
// order of Refresh().
|
||||||
|
//
|
||||||
|
// GetSpecDirErrors returns any errors related to the configured
|
||||||
|
// Spec directories.
|
||||||
|
type RegistryRefresher interface {
|
||||||
|
Configure(...Option) error
|
||||||
|
Refresh() error
|
||||||
|
GetErrors() map[string][]error
|
||||||
|
GetSpecDirectories() []string
|
||||||
|
GetSpecDirErrors() map[string]error
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegistryResolver is the registry interface for injecting CDI
|
||||||
|
// devices into an OCI Spec.
|
||||||
|
//
|
||||||
|
// InjectDevices takes an OCI Spec and injects into it a set of
|
||||||
|
// CDI devices given by qualified name. It returns the names of
|
||||||
|
// any unresolved devices and an error if injection fails.
|
||||||
|
type RegistryResolver interface {
|
||||||
|
InjectDevices(spec *oci.Spec, device ...string) (unresolved []string, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegistryDeviceDB is the registry interface for querying devices.
|
||||||
|
//
|
||||||
|
// GetDevice returns the CDI device for the given qualified name. If
|
||||||
|
// the device is not GetDevice returns nil.
|
||||||
|
//
|
||||||
|
// ListDevices returns a slice with the names of qualified device
|
||||||
|
// known. The returned slice is sorted.
|
||||||
|
type RegistryDeviceDB interface {
|
||||||
|
GetDevice(device string) *Device
|
||||||
|
ListDevices() []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegistrySpecDB is the registry interface for querying CDI Specs.
|
||||||
|
//
|
||||||
|
// ListVendors returns a slice with all vendors known. The returned
|
||||||
|
// slice is sorted.
|
||||||
|
//
|
||||||
|
// ListClasses returns a slice with all classes known. The returned
|
||||||
|
// slice is sorted.
|
||||||
|
//
|
||||||
|
// GetVendorSpecs returns a slice of all Specs for the vendor.
|
||||||
|
//
|
||||||
|
// GetSpecErrors returns any errors for the Spec encountered during
|
||||||
|
// the last cache refresh.
|
||||||
|
//
|
||||||
|
// WriteSpec writes the Spec with the given content and name to the
|
||||||
|
// last Spec directory.
|
||||||
|
type RegistrySpecDB interface {
|
||||||
|
ListVendors() []string
|
||||||
|
ListClasses() []string
|
||||||
|
GetVendorSpecs(vendor string) []*Spec
|
||||||
|
GetSpecErrors(*Spec) []error
|
||||||
|
WriteSpec(raw *cdi.Spec, name string) error
|
||||||
|
RemoveSpec(name string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type registry struct {
|
||||||
|
*Cache
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Registry = ®istry{}
|
||||||
|
|
||||||
|
var (
|
||||||
|
reg *registry
|
||||||
|
initOnce sync.Once
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetRegistry returns the CDI registry. If any options are given, those
|
||||||
|
// are applied to the registry.
|
||||||
|
func GetRegistry(options ...Option) Registry {
|
||||||
|
var new bool
|
||||||
|
initOnce.Do(func() {
|
||||||
|
reg, _ = getRegistry(options...)
|
||||||
|
new = true
|
||||||
|
})
|
||||||
|
if !new && len(options) > 0 {
|
||||||
|
reg.Configure(options...)
|
||||||
|
reg.Refresh()
|
||||||
|
}
|
||||||
|
return reg
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceDB returns the registry interface for querying devices.
|
||||||
|
func (r *registry) DeviceDB() RegistryDeviceDB {
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// SpecDB returns the registry interface for querying Specs.
|
||||||
|
func (r *registry) SpecDB() RegistrySpecDB {
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRegistry(options ...Option) (*registry, error) {
|
||||||
|
c, err := NewCache(options...)
|
||||||
|
return ®istry{c}, err
|
||||||
|
}
|
114
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec-dirs.go
generated
vendored
Normal file
114
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec-dirs.go
generated
vendored
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DefaultStaticDir is the default directory for static CDI Specs.
|
||||||
|
DefaultStaticDir = "/etc/cdi"
|
||||||
|
// DefaultDynamicDir is the default directory for generated CDI Specs
|
||||||
|
DefaultDynamicDir = "/var/run/cdi"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// DefaultSpecDirs is the default Spec directory configuration.
|
||||||
|
// While altering this variable changes the package defaults,
|
||||||
|
// the preferred way of overriding the default directories is
|
||||||
|
// to use a WithSpecDirs options. Otherwise the change is only
|
||||||
|
// effective if it takes place before creating the Registry or
|
||||||
|
// other Cache instances.
|
||||||
|
DefaultSpecDirs = []string{DefaultStaticDir, DefaultDynamicDir}
|
||||||
|
// ErrStopScan can be returned from a ScanSpecFunc to stop the scan.
|
||||||
|
ErrStopScan = errors.New("stop Spec scan")
|
||||||
|
)
|
||||||
|
|
||||||
|
// WithSpecDirs returns an option to override the CDI Spec directories.
|
||||||
|
func WithSpecDirs(dirs ...string) Option {
|
||||||
|
return func(c *Cache) error {
|
||||||
|
specDirs := make([]string, len(dirs))
|
||||||
|
for i, dir := range dirs {
|
||||||
|
specDirs[i] = filepath.Clean(dir)
|
||||||
|
}
|
||||||
|
c.specDirs = specDirs
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// scanSpecFunc is a function for processing CDI Spec files.
|
||||||
|
type scanSpecFunc func(string, int, *Spec, error) error
|
||||||
|
|
||||||
|
// ScanSpecDirs scans the given directories looking for CDI Spec files,
|
||||||
|
// which are all files with a '.json' or '.yaml' suffix. For every Spec
|
||||||
|
// file discovered, ScanSpecDirs loads a Spec from the file then calls
|
||||||
|
// the scan function passing it the path to the file, the priority (the
|
||||||
|
// index of the directory in the slice of directories given), the Spec
|
||||||
|
// itself, and any error encountered while loading the Spec.
|
||||||
|
//
|
||||||
|
// Scanning stops once all files have been processed or when the scan
|
||||||
|
// function returns an error. The result of ScanSpecDirs is the error
|
||||||
|
// returned by the scan function, if any. The special error ErrStopScan
|
||||||
|
// can be used to terminate the scan gracefully without ScanSpecDirs
|
||||||
|
// returning an error. ScanSpecDirs silently skips any subdirectories.
|
||||||
|
func scanSpecDirs(dirs []string, scanFn scanSpecFunc) error {
|
||||||
|
var (
|
||||||
|
spec *Spec
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
for priority, dir := range dirs {
|
||||||
|
err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||||
|
// for initial stat failure Walk calls us with nil info
|
||||||
|
if info == nil {
|
||||||
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// first call from Walk is for dir itself, others we skip
|
||||||
|
if info.IsDir() {
|
||||||
|
if path == dir {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return filepath.SkipDir
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore obviously non-Spec files
|
||||||
|
if ext := filepath.Ext(path); ext != ".json" && ext != ".yaml" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return scanFn(path, priority, nil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
spec, err = ReadSpec(path, priority)
|
||||||
|
return scanFn(path, priority, spec, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil && err != ErrStopScan {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
352
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec.go
generated
vendored
Normal file
352
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec.go
generated
vendored
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
oci "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
"sigs.k8s.io/yaml"
|
||||||
|
|
||||||
|
"github.com/container-orchestrated-devices/container-device-interface/internal/validation"
|
||||||
|
cdi "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// defaultSpecExt is the file extension for the default encoding.
|
||||||
|
defaultSpecExt = ".yaml"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Externally set CDI Spec validation function.
|
||||||
|
specValidator func(*cdi.Spec) error
|
||||||
|
validatorLock sync.RWMutex
|
||||||
|
)
|
||||||
|
|
||||||
|
// Spec represents a single CDI Spec. It is usually loaded from a
|
||||||
|
// file and stored in a cache. The Spec has an associated priority.
|
||||||
|
// This priority is inherited from the associated priority of the
|
||||||
|
// CDI Spec directory that contains the CDI Spec file and is used
|
||||||
|
// to resolve conflicts if multiple CDI Spec files contain entries
|
||||||
|
// for the same fully qualified device.
|
||||||
|
type Spec struct {
|
||||||
|
*cdi.Spec
|
||||||
|
vendor string
|
||||||
|
class string
|
||||||
|
path string
|
||||||
|
priority int
|
||||||
|
devices map[string]*Device
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadSpec reads the given CDI Spec file. The resulting Spec is
|
||||||
|
// assigned the given priority. If reading or parsing the Spec
|
||||||
|
// data fails ReadSpec returns a nil Spec and an error.
|
||||||
|
func ReadSpec(path string, priority int) (*Spec, error) {
|
||||||
|
data, err := ioutil.ReadFile(path)
|
||||||
|
switch {
|
||||||
|
case os.IsNotExist(err):
|
||||||
|
return nil, err
|
||||||
|
case err != nil:
|
||||||
|
return nil, fmt.Errorf("failed to read CDI Spec %q: %w", path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
raw, err := ParseSpec(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse CDI Spec %q: %w", path, err)
|
||||||
|
}
|
||||||
|
if raw == nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse CDI Spec %q, no Spec data", path)
|
||||||
|
}
|
||||||
|
|
||||||
|
spec, err := newSpec(raw, path, priority)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return spec, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newSpec creates a new Spec from the given CDI Spec data. The
|
||||||
|
// Spec is marked as loaded from the given path with the given
|
||||||
|
// priority. If Spec data validation fails newSpec returns a nil
|
||||||
|
// Spec and an error.
|
||||||
|
func newSpec(raw *cdi.Spec, path string, priority int) (*Spec, error) {
|
||||||
|
err := validateSpec(raw)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
spec := &Spec{
|
||||||
|
Spec: raw,
|
||||||
|
path: filepath.Clean(path),
|
||||||
|
priority: priority,
|
||||||
|
}
|
||||||
|
|
||||||
|
if ext := filepath.Ext(spec.path); ext != ".yaml" && ext != ".json" {
|
||||||
|
spec.path += defaultSpecExt
|
||||||
|
}
|
||||||
|
|
||||||
|
spec.vendor, spec.class = ParseQualifier(spec.Kind)
|
||||||
|
|
||||||
|
if spec.devices, err = spec.validate(); err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid CDI Spec: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return spec, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the CDI Spec to the file associated with it during instantiation
|
||||||
|
// by newSpec() or ReadSpec().
|
||||||
|
func (s *Spec) write(overwrite bool) error {
|
||||||
|
var (
|
||||||
|
data []byte
|
||||||
|
dir string
|
||||||
|
tmp *os.File
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
err = validateSpec(s.Spec)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if filepath.Ext(s.path) == ".yaml" {
|
||||||
|
data, err = yaml.Marshal(s.Spec)
|
||||||
|
data = append([]byte("---\n"), data...)
|
||||||
|
} else {
|
||||||
|
data, err = json.Marshal(s.Spec)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to marshal Spec file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dir = filepath.Dir(s.path)
|
||||||
|
err = os.MkdirAll(dir, 0o755)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create Spec dir: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp, err = os.CreateTemp(dir, "spec.*.tmp")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create Spec file: %w", err)
|
||||||
|
}
|
||||||
|
_, err = tmp.Write(data)
|
||||||
|
tmp.Close()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to write Spec file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = renameIn(dir, filepath.Base(tmp.Name()), filepath.Base(s.path), overwrite)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
os.Remove(tmp.Name())
|
||||||
|
err = fmt.Errorf("failed to write Spec file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVendor returns the vendor of this Spec.
|
||||||
|
func (s *Spec) GetVendor() string {
|
||||||
|
return s.vendor
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetClass returns the device class of this Spec.
|
||||||
|
func (s *Spec) GetClass() string {
|
||||||
|
return s.class
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDevice returns the device for the given unqualified name.
|
||||||
|
func (s *Spec) GetDevice(name string) *Device {
|
||||||
|
return s.devices[name]
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPath returns the filesystem path of this Spec.
|
||||||
|
func (s *Spec) GetPath() string {
|
||||||
|
return s.path
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPriority returns the priority of this Spec.
|
||||||
|
func (s *Spec) GetPriority() int {
|
||||||
|
return s.priority
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApplyEdits applies the Spec's global-scope container edits to an OCI Spec.
|
||||||
|
func (s *Spec) ApplyEdits(ociSpec *oci.Spec) error {
|
||||||
|
return s.edits().Apply(ociSpec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// edits returns the applicable global container edits for this spec.
|
||||||
|
func (s *Spec) edits() *ContainerEdits {
|
||||||
|
return &ContainerEdits{&s.ContainerEdits}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the Spec.
|
||||||
|
func (s *Spec) validate() (map[string]*Device, error) {
|
||||||
|
if err := validateVersion(s.Version); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
minVersion, err := MinimumRequiredVersion(s.Spec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not determine minimum required version: %v", err)
|
||||||
|
}
|
||||||
|
if newVersion(minVersion).IsGreaterThan(newVersion(s.Version)) {
|
||||||
|
return nil, fmt.Errorf("the spec version must be at least v%v", minVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateVendorName(s.vendor); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := ValidateClassName(s.class); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := validation.ValidateSpecAnnotations(s.Kind, s.Annotations); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := s.edits().Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
devices := make(map[string]*Device)
|
||||||
|
for _, d := range s.Devices {
|
||||||
|
dev, err := newDevice(s, d)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed add device %q: %w", d.Name, err)
|
||||||
|
}
|
||||||
|
if _, conflict := devices[d.Name]; conflict {
|
||||||
|
return nil, fmt.Errorf("invalid spec, multiple device %q", d.Name)
|
||||||
|
}
|
||||||
|
devices[d.Name] = dev
|
||||||
|
}
|
||||||
|
|
||||||
|
return devices, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateVersion checks whether the specified spec version is supported.
|
||||||
|
func validateVersion(version string) error {
|
||||||
|
if !validSpecVersions.isValidVersion(version) {
|
||||||
|
return fmt.Errorf("invalid version %q", version)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseSpec parses CDI Spec data into a raw CDI Spec.
|
||||||
|
func ParseSpec(data []byte) (*cdi.Spec, error) {
|
||||||
|
var raw *cdi.Spec
|
||||||
|
err := yaml.UnmarshalStrict(data, &raw)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to unmarshal CDI Spec: %w", err)
|
||||||
|
}
|
||||||
|
return raw, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSpecValidator sets a CDI Spec validator function. This function
|
||||||
|
// is used for extra CDI Spec content validation whenever a Spec file
|
||||||
|
// loaded (using ReadSpec() or written (using WriteSpec()).
|
||||||
|
func SetSpecValidator(fn func(*cdi.Spec) error) {
|
||||||
|
validatorLock.Lock()
|
||||||
|
defer validatorLock.Unlock()
|
||||||
|
specValidator = fn
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateSpec validates the Spec using the extneral validator.
|
||||||
|
func validateSpec(raw *cdi.Spec) error {
|
||||||
|
validatorLock.RLock()
|
||||||
|
defer validatorLock.RUnlock()
|
||||||
|
|
||||||
|
if specValidator == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err := specValidator(raw)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Spec validation failed: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateSpecName generates a vendor+class scoped Spec file name. The
|
||||||
|
// name can be passed to WriteSpec() to write a Spec file to the file
|
||||||
|
// system.
|
||||||
|
//
|
||||||
|
// vendor and class should match the vendor and class of the CDI Spec.
|
||||||
|
// The file name is generated without a ".json" or ".yaml" extension.
|
||||||
|
// The caller can append the desired extension to choose a particular
|
||||||
|
// encoding. Otherwise WriteSpec() will use its default encoding.
|
||||||
|
//
|
||||||
|
// This function always returns the same name for the same vendor/class
|
||||||
|
// combination. Therefore it cannot be used as such to generate multiple
|
||||||
|
// Spec file names for a single vendor and class.
|
||||||
|
func GenerateSpecName(vendor, class string) string {
|
||||||
|
return vendor + "-" + class
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateTransientSpecName generates a vendor+class scoped transient
|
||||||
|
// Spec file name. The name can be passed to WriteSpec() to write a Spec
|
||||||
|
// file to the file system.
|
||||||
|
//
|
||||||
|
// Transient Specs are those whose lifecycle is tied to that of some
|
||||||
|
// external entity, for instance a container. vendor and class should
|
||||||
|
// match the vendor and class of the CDI Spec. transientID should be
|
||||||
|
// unique among all CDI users on the same host that might generate
|
||||||
|
// transient Spec files using the same vendor/class combination. If
|
||||||
|
// the external entity to which the lifecycle of the transient Spec
|
||||||
|
// is tied to has a unique ID of its own, then this is usually a
|
||||||
|
// good choice for transientID.
|
||||||
|
//
|
||||||
|
// The file name is generated without a ".json" or ".yaml" extension.
|
||||||
|
// The caller can append the desired extension to choose a particular
|
||||||
|
// encoding. Otherwise WriteSpec() will use its default encoding.
|
||||||
|
func GenerateTransientSpecName(vendor, class, transientID string) string {
|
||||||
|
transientID = strings.ReplaceAll(transientID, "/", "_")
|
||||||
|
return GenerateSpecName(vendor, class) + "_" + transientID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateNameForSpec generates a name for the given Spec using
|
||||||
|
// GenerateSpecName with the vendor and class taken from the Spec.
|
||||||
|
// On success it returns the generated name and a nil error. If
|
||||||
|
// the Spec does not contain a valid vendor or class, it returns
|
||||||
|
// an empty name and a non-nil error.
|
||||||
|
func GenerateNameForSpec(raw *cdi.Spec) (string, error) {
|
||||||
|
vendor, class := ParseQualifier(raw.Kind)
|
||||||
|
if vendor == "" {
|
||||||
|
return "", fmt.Errorf("invalid vendor/class %q in Spec", raw.Kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
return GenerateSpecName(vendor, class), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateNameForTransientSpec generates a name for the given transient
|
||||||
|
// Spec using GenerateTransientSpecName with the vendor and class taken
|
||||||
|
// from the Spec. On success it returns the generated name and a nil error.
|
||||||
|
// If the Spec does not contain a valid vendor or class, it returns an
|
||||||
|
// an empty name and a non-nil error.
|
||||||
|
func GenerateNameForTransientSpec(raw *cdi.Spec, transientID string) (string, error) {
|
||||||
|
vendor, class := ParseQualifier(raw.Kind)
|
||||||
|
if vendor == "" {
|
||||||
|
return "", fmt.Errorf("invalid vendor/class %q in Spec", raw.Kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
return GenerateTransientSpecName(vendor, class, transientID), nil
|
||||||
|
}
|
48
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec_linux.go
generated
vendored
Normal file
48
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec_linux.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2022 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Rename src to dst, both relative to the directory dir. If dst already exists
|
||||||
|
// refuse renaming with an error unless overwrite is explicitly asked for.
|
||||||
|
func renameIn(dir, src, dst string, overwrite bool) error {
|
||||||
|
var flags uint
|
||||||
|
|
||||||
|
dirf, err := os.Open(dir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("rename failed: %w", err)
|
||||||
|
}
|
||||||
|
defer dirf.Close()
|
||||||
|
|
||||||
|
if !overwrite {
|
||||||
|
flags = unix.RENAME_NOREPLACE
|
||||||
|
}
|
||||||
|
|
||||||
|
dirFd := int(dirf.Fd())
|
||||||
|
err = unix.Renameat2(dirFd, src, dirFd, dst, flags)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("rename failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
39
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec_other.go
generated
vendored
Normal file
39
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec_other.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//go:build !linux
|
||||||
|
// +build !linux
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright © 2022 The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Rename src to dst, both relative to the directory dir. If dst already exists
|
||||||
|
// refuse renaming with an error unless overwrite is explicitly asked for.
|
||||||
|
func renameIn(dir, src, dst string, overwrite bool) error {
|
||||||
|
src = filepath.Join(dir, src)
|
||||||
|
dst = filepath.Join(dir, dst)
|
||||||
|
|
||||||
|
_, err := os.Stat(dst)
|
||||||
|
if err == nil && !overwrite {
|
||||||
|
return os.ErrExist
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.Rename(src, dst)
|
||||||
|
}
|
188
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/version.go
generated
vendored
Normal file
188
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/version.go
generated
vendored
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
Copyright © The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/mod/semver"
|
||||||
|
|
||||||
|
"github.com/container-orchestrated-devices/container-device-interface/pkg/parser"
|
||||||
|
cdi "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// CurrentVersion is the current version of the CDI Spec.
|
||||||
|
CurrentVersion = cdi.CurrentVersion
|
||||||
|
|
||||||
|
// vCurrent is the current version as a semver-comparable type
|
||||||
|
vCurrent version = "v" + CurrentVersion
|
||||||
|
|
||||||
|
// These represent the released versions of the CDI specification
|
||||||
|
v010 version = "v0.1.0"
|
||||||
|
v020 version = "v0.2.0"
|
||||||
|
v030 version = "v0.3.0"
|
||||||
|
v040 version = "v0.4.0"
|
||||||
|
v050 version = "v0.5.0"
|
||||||
|
v060 version = "v0.6.0"
|
||||||
|
|
||||||
|
// vEarliest is the earliest supported version of the CDI specification
|
||||||
|
vEarliest version = v030
|
||||||
|
)
|
||||||
|
|
||||||
|
// validSpecVersions stores a map of spec versions to functions to check the required versions.
|
||||||
|
// Adding new fields / spec versions requires that a `requiredFunc` be implemented and
|
||||||
|
// this map be updated.
|
||||||
|
var validSpecVersions = requiredVersionMap{
|
||||||
|
v010: nil,
|
||||||
|
v020: nil,
|
||||||
|
v030: nil,
|
||||||
|
v040: requiresV040,
|
||||||
|
v050: requiresV050,
|
||||||
|
v060: requiresV060,
|
||||||
|
}
|
||||||
|
|
||||||
|
// MinimumRequiredVersion determines the minimum spec version for the input spec.
|
||||||
|
func MinimumRequiredVersion(spec *cdi.Spec) (string, error) {
|
||||||
|
minVersion := validSpecVersions.requiredVersion(spec)
|
||||||
|
return minVersion.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// version represents a semantic version string
|
||||||
|
type version string
|
||||||
|
|
||||||
|
// newVersion creates a version that can be used for semantic version comparisons.
|
||||||
|
func newVersion(v string) version {
|
||||||
|
return version("v" + strings.TrimPrefix(v, "v"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation of the version.
|
||||||
|
// This trims a leading v if present.
|
||||||
|
func (v version) String() string {
|
||||||
|
return strings.TrimPrefix(string(v), "v")
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsGreaterThan checks with a version is greater than the specified version.
|
||||||
|
func (v version) IsGreaterThan(o version) bool {
|
||||||
|
return semver.Compare(string(v), string(o)) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsLatest checks whether the version is the latest supported version
|
||||||
|
func (v version) IsLatest() bool {
|
||||||
|
return v == vCurrent
|
||||||
|
}
|
||||||
|
|
||||||
|
type requiredFunc func(*cdi.Spec) bool
|
||||||
|
|
||||||
|
type requiredVersionMap map[version]requiredFunc
|
||||||
|
|
||||||
|
// isValidVersion checks whether the specified version is valid.
|
||||||
|
// A version is valid if it is contained in the required version map.
|
||||||
|
func (r requiredVersionMap) isValidVersion(specVersion string) bool {
|
||||||
|
_, ok := validSpecVersions[newVersion(specVersion)]
|
||||||
|
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// requiredVersion returns the minimum version required for the given spec
|
||||||
|
func (r requiredVersionMap) requiredVersion(spec *cdi.Spec) version {
|
||||||
|
minVersion := vEarliest
|
||||||
|
|
||||||
|
for v, isRequired := range validSpecVersions {
|
||||||
|
if isRequired == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if isRequired(spec) && v.IsGreaterThan(minVersion) {
|
||||||
|
minVersion = v
|
||||||
|
}
|
||||||
|
// If we have already detected the latest version then no later version could be detected
|
||||||
|
if minVersion.IsLatest() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return minVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
// requiresV060 returns true if the spec uses v0.6.0 features
|
||||||
|
func requiresV060(spec *cdi.Spec) bool {
|
||||||
|
// The v0.6.0 spec allows annotations to be specified at a spec level
|
||||||
|
for range spec.Annotations {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// The v0.6.0 spec allows annotations to be specified at a device level
|
||||||
|
for _, d := range spec.Devices {
|
||||||
|
for range d.Annotations {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The v0.6.0 spec allows dots "." in Kind name label (class)
|
||||||
|
vendor, class := parser.ParseQualifier(spec.Kind)
|
||||||
|
if vendor != "" {
|
||||||
|
if strings.ContainsRune(class, '.') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// requiresV050 returns true if the spec uses v0.5.0 features
|
||||||
|
func requiresV050(spec *cdi.Spec) bool {
|
||||||
|
var edits []*cdi.ContainerEdits
|
||||||
|
|
||||||
|
for _, d := range spec.Devices {
|
||||||
|
// The v0.5.0 spec allowed device names to start with a digit instead of requiring a letter
|
||||||
|
if len(d.Name) > 0 && !parser.IsLetter(rune(d.Name[0])) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
edits = append(edits, &d.ContainerEdits)
|
||||||
|
}
|
||||||
|
|
||||||
|
edits = append(edits, &spec.ContainerEdits)
|
||||||
|
for _, e := range edits {
|
||||||
|
for _, dn := range e.DeviceNodes {
|
||||||
|
// The HostPath field was added in v0.5.0
|
||||||
|
if dn.HostPath != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// requiresV040 returns true if the spec uses v0.4.0 features
|
||||||
|
func requiresV040(spec *cdi.Spec) bool {
|
||||||
|
var edits []*cdi.ContainerEdits
|
||||||
|
|
||||||
|
for _, d := range spec.Devices {
|
||||||
|
edits = append(edits, &d.ContainerEdits)
|
||||||
|
}
|
||||||
|
|
||||||
|
edits = append(edits, &spec.ContainerEdits)
|
||||||
|
for _, e := range edits {
|
||||||
|
for _, m := range e.Mounts {
|
||||||
|
// The Type field was added in v0.4.0
|
||||||
|
if m.Type != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
212
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/parser/parser.go
generated
vendored
Normal file
212
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/parser/parser.go
generated
vendored
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
/*
|
||||||
|
Copyright © The CDI Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package parser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// QualifiedName returns the qualified name for a device.
|
||||||
|
// The syntax for a qualified device names is
|
||||||
|
//
|
||||||
|
// "<vendor>/<class>=<name>".
|
||||||
|
//
|
||||||
|
// A valid vendor and class name may contain the following runes:
|
||||||
|
//
|
||||||
|
// 'A'-'Z', 'a'-'z', '0'-'9', '.', '-', '_'.
|
||||||
|
//
|
||||||
|
// A valid device name may contain the following runes:
|
||||||
|
//
|
||||||
|
// 'A'-'Z', 'a'-'z', '0'-'9', '-', '_', '.', ':'
|
||||||
|
func QualifiedName(vendor, class, name string) string {
|
||||||
|
return vendor + "/" + class + "=" + name
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsQualifiedName tests if a device name is qualified.
|
||||||
|
func IsQualifiedName(device string) bool {
|
||||||
|
_, _, _, err := ParseQualifiedName(device)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseQualifiedName splits a qualified name into device vendor, class,
|
||||||
|
// and name. If the device fails to parse as a qualified name, or if any
|
||||||
|
// of the split components fail to pass syntax validation, vendor and
|
||||||
|
// class are returned as empty, together with the verbatim input as the
|
||||||
|
// name and an error describing the reason for failure.
|
||||||
|
func ParseQualifiedName(device string) (string, string, string, error) {
|
||||||
|
vendor, class, name := ParseDevice(device)
|
||||||
|
|
||||||
|
if vendor == "" {
|
||||||
|
return "", "", device, fmt.Errorf("unqualified device %q, missing vendor", device)
|
||||||
|
}
|
||||||
|
if class == "" {
|
||||||
|
return "", "", device, fmt.Errorf("unqualified device %q, missing class", device)
|
||||||
|
}
|
||||||
|
if name == "" {
|
||||||
|
return "", "", device, fmt.Errorf("unqualified device %q, missing device name", device)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ValidateVendorName(vendor); err != nil {
|
||||||
|
return "", "", device, fmt.Errorf("invalid device %q: %w", device, err)
|
||||||
|
}
|
||||||
|
if err := ValidateClassName(class); err != nil {
|
||||||
|
return "", "", device, fmt.Errorf("invalid device %q: %w", device, err)
|
||||||
|
}
|
||||||
|
if err := ValidateDeviceName(name); err != nil {
|
||||||
|
return "", "", device, fmt.Errorf("invalid device %q: %w", device, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return vendor, class, name, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDevice tries to split a device name into vendor, class, and name.
|
||||||
|
// If this fails, for instance in the case of unqualified device names,
|
||||||
|
// ParseDevice returns an empty vendor and class together with name set
|
||||||
|
// to the verbatim input.
|
||||||
|
func ParseDevice(device string) (string, string, string) {
|
||||||
|
if device == "" || device[0] == '/' {
|
||||||
|
return "", "", device
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.SplitN(device, "=", 2)
|
||||||
|
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
|
||||||
|
return "", "", device
|
||||||
|
}
|
||||||
|
|
||||||
|
name := parts[1]
|
||||||
|
vendor, class := ParseQualifier(parts[0])
|
||||||
|
if vendor == "" {
|
||||||
|
return "", "", device
|
||||||
|
}
|
||||||
|
|
||||||
|
return vendor, class, name
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseQualifier splits a device qualifier into vendor and class.
|
||||||
|
// The syntax for a device qualifier is
|
||||||
|
//
|
||||||
|
// "<vendor>/<class>"
|
||||||
|
//
|
||||||
|
// If parsing fails, an empty vendor and the class set to the
|
||||||
|
// verbatim input is returned.
|
||||||
|
func ParseQualifier(kind string) (string, string) {
|
||||||
|
parts := strings.SplitN(kind, "/", 2)
|
||||||
|
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
|
||||||
|
return "", kind
|
||||||
|
}
|
||||||
|
return parts[0], parts[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateVendorName checks the validity of a vendor name.
|
||||||
|
// A vendor name may contain the following ASCII characters:
|
||||||
|
// - upper- and lowercase letters ('A'-'Z', 'a'-'z')
|
||||||
|
// - digits ('0'-'9')
|
||||||
|
// - underscore, dash, and dot ('_', '-', and '.')
|
||||||
|
func ValidateVendorName(vendor string) error {
|
||||||
|
err := validateVendorOrClassName(vendor)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("invalid vendor. %w", err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateClassName checks the validity of class name.
|
||||||
|
// A class name may contain the following ASCII characters:
|
||||||
|
// - upper- and lowercase letters ('A'-'Z', 'a'-'z')
|
||||||
|
// - digits ('0'-'9')
|
||||||
|
// - underscore, dash, and dot ('_', '-', and '.')
|
||||||
|
func ValidateClassName(class string) error {
|
||||||
|
err := validateVendorOrClassName(class)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("invalid class. %w", err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateVendorOrClassName checks the validity of vendor or class name.
|
||||||
|
// A name may contain the following ASCII characters:
|
||||||
|
// - upper- and lowercase letters ('A'-'Z', 'a'-'z')
|
||||||
|
// - digits ('0'-'9')
|
||||||
|
// - underscore, dash, and dot ('_', '-', and '.')
|
||||||
|
func validateVendorOrClassName(name string) error {
|
||||||
|
if name == "" {
|
||||||
|
return fmt.Errorf("empty name")
|
||||||
|
}
|
||||||
|
if !IsLetter(rune(name[0])) {
|
||||||
|
return fmt.Errorf("%q, should start with letter", name)
|
||||||
|
}
|
||||||
|
for _, c := range string(name[1 : len(name)-1]) {
|
||||||
|
switch {
|
||||||
|
case IsAlphaNumeric(c):
|
||||||
|
case c == '_' || c == '-' || c == '.':
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid character '%c' in name %q",
|
||||||
|
c, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !IsAlphaNumeric(rune(name[len(name)-1])) {
|
||||||
|
return fmt.Errorf("%q, should end with a letter or digit", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateDeviceName checks the validity of a device name.
|
||||||
|
// A device name may contain the following ASCII characters:
|
||||||
|
// - upper- and lowercase letters ('A'-'Z', 'a'-'z')
|
||||||
|
// - digits ('0'-'9')
|
||||||
|
// - underscore, dash, dot, colon ('_', '-', '.', ':')
|
||||||
|
func ValidateDeviceName(name string) error {
|
||||||
|
if name == "" {
|
||||||
|
return fmt.Errorf("invalid (empty) device name")
|
||||||
|
}
|
||||||
|
if !IsAlphaNumeric(rune(name[0])) {
|
||||||
|
return fmt.Errorf("invalid class %q, should start with a letter or digit", name)
|
||||||
|
}
|
||||||
|
if len(name) == 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, c := range string(name[1 : len(name)-1]) {
|
||||||
|
switch {
|
||||||
|
case IsAlphaNumeric(c):
|
||||||
|
case c == '_' || c == '-' || c == '.' || c == ':':
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid character '%c' in device name %q",
|
||||||
|
c, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !IsAlphaNumeric(rune(name[len(name)-1])) {
|
||||||
|
return fmt.Errorf("invalid name %q, should end with a letter or digit", name)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsLetter reports whether the rune is a letter.
|
||||||
|
func IsLetter(c rune) bool {
|
||||||
|
return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDigit reports whether the rune is a digit.
|
||||||
|
func IsDigit(c rune) bool {
|
||||||
|
return '0' <= c && c <= '9'
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAlphaNumeric reports whether the rune is a letter or digit.
|
||||||
|
func IsAlphaNumeric(c rune) bool {
|
||||||
|
return IsLetter(c) || IsDigit(c)
|
||||||
|
}
|
62
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/specs-go/config.go
generated
vendored
Normal file
62
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/specs-go/config.go
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package specs
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
// CurrentVersion is the current version of the Spec.
|
||||||
|
const CurrentVersion = "0.6.0"
|
||||||
|
|
||||||
|
// Spec is the base configuration for CDI
|
||||||
|
type Spec struct {
|
||||||
|
Version string `json:"cdiVersion"`
|
||||||
|
Kind string `json:"kind"`
|
||||||
|
// Annotations add meta information per CDI spec. Note these are CDI-specific and do not affect container metadata.
|
||||||
|
Annotations map[string]string `json:"annotations,omitempty"`
|
||||||
|
Devices []Device `json:"devices"`
|
||||||
|
ContainerEdits ContainerEdits `json:"containerEdits,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Device is a "Device" a container runtime can add to a container
|
||||||
|
type Device struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
// Annotations add meta information per device. Note these are CDI-specific and do not affect container metadata.
|
||||||
|
Annotations map[string]string `json:"annotations,omitempty"`
|
||||||
|
ContainerEdits ContainerEdits `json:"containerEdits"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerEdits are edits a container runtime must make to the OCI spec to expose the device.
|
||||||
|
type ContainerEdits struct {
|
||||||
|
Env []string `json:"env,omitempty"`
|
||||||
|
DeviceNodes []*DeviceNode `json:"deviceNodes,omitempty"`
|
||||||
|
Hooks []*Hook `json:"hooks,omitempty"`
|
||||||
|
Mounts []*Mount `json:"mounts,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceNode represents a device node that needs to be added to the OCI spec.
|
||||||
|
type DeviceNode struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
HostPath string `json:"hostPath,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
Major int64 `json:"major,omitempty"`
|
||||||
|
Minor int64 `json:"minor,omitempty"`
|
||||||
|
FileMode *os.FileMode `json:"fileMode,omitempty"`
|
||||||
|
Permissions string `json:"permissions,omitempty"`
|
||||||
|
UID *uint32 `json:"uid,omitempty"`
|
||||||
|
GID *uint32 `json:"gid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mount represents a mount that needs to be added to the OCI spec.
|
||||||
|
type Mount struct {
|
||||||
|
HostPath string `json:"hostPath"`
|
||||||
|
ContainerPath string `json:"containerPath"`
|
||||||
|
Options []string `json:"options,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook represents a hook that needs to be added to the OCI spec.
|
||||||
|
type Hook struct {
|
||||||
|
HookName string `json:"hookName"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Args []string `json:"args,omitempty"`
|
||||||
|
Env []string `json:"env,omitempty"`
|
||||||
|
Timeout *int `json:"timeout,omitempty"`
|
||||||
|
}
|
113
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/specs-go/oci.go
generated
vendored
Normal file
113
src/runtime/vendor/github.com/container-orchestrated-devices/container-device-interface/specs-go/oci.go
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
package specs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ApplyOCIEditsForDevice applies devices OCI edits, in other words
|
||||||
|
// it finds the device in the CDI spec and applies the OCI patches that device
|
||||||
|
// requires to the OCI specification.
|
||||||
|
func ApplyOCIEditsForDevice(config *spec.Spec, cdi *Spec, dev string) error {
|
||||||
|
for _, d := range cdi.Devices {
|
||||||
|
if d.Name != dev {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApplyEditsToOCISpec(config, &d.ContainerEdits)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("CDI: device %q not found for spec %q", dev, cdi.Kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApplyOCIEdits applies the OCI edits the CDI spec declares globally
|
||||||
|
func ApplyOCIEdits(config *spec.Spec, cdi *Spec) error {
|
||||||
|
return ApplyEditsToOCISpec(config, &cdi.ContainerEdits)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApplyEditsToOCISpec applies the specified edits to the OCI spec.
|
||||||
|
func ApplyEditsToOCISpec(config *spec.Spec, edits *ContainerEdits) error {
|
||||||
|
if config == nil {
|
||||||
|
return errors.New("spec is nil")
|
||||||
|
}
|
||||||
|
if edits == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(edits.Env) > 0 {
|
||||||
|
if config.Process == nil {
|
||||||
|
config.Process = &spec.Process{}
|
||||||
|
}
|
||||||
|
config.Process.Env = append(config.Process.Env, edits.Env...)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, d := range edits.DeviceNodes {
|
||||||
|
if config.Linux == nil {
|
||||||
|
config.Linux = &spec.Linux{}
|
||||||
|
}
|
||||||
|
config.Linux.Devices = append(config.Linux.Devices, d.ToOCI())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, m := range edits.Mounts {
|
||||||
|
config.Mounts = append(config.Mounts, m.ToOCI())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, h := range edits.Hooks {
|
||||||
|
if config.Hooks == nil {
|
||||||
|
config.Hooks = &spec.Hooks{}
|
||||||
|
}
|
||||||
|
switch h.HookName {
|
||||||
|
case "prestart":
|
||||||
|
config.Hooks.Prestart = append(config.Hooks.Prestart, h.ToOCI())
|
||||||
|
case "createRuntime":
|
||||||
|
config.Hooks.CreateRuntime = append(config.Hooks.CreateRuntime, h.ToOCI())
|
||||||
|
case "createContainer":
|
||||||
|
config.Hooks.CreateContainer = append(config.Hooks.CreateContainer, h.ToOCI())
|
||||||
|
case "startContainer":
|
||||||
|
config.Hooks.StartContainer = append(config.Hooks.StartContainer, h.ToOCI())
|
||||||
|
case "poststart":
|
||||||
|
config.Hooks.Poststart = append(config.Hooks.Poststart, h.ToOCI())
|
||||||
|
case "poststop":
|
||||||
|
config.Hooks.Poststop = append(config.Hooks.Poststop, h.ToOCI())
|
||||||
|
default:
|
||||||
|
fmt.Printf("CDI: Unknown hook %q\n", h.HookName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToOCI returns the opencontainers runtime Spec Hook for this Hook.
|
||||||
|
func (h *Hook) ToOCI() spec.Hook {
|
||||||
|
return spec.Hook{
|
||||||
|
Path: h.Path,
|
||||||
|
Args: h.Args,
|
||||||
|
Env: h.Env,
|
||||||
|
Timeout: h.Timeout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToOCI returns the opencontainers runtime Spec Mount for this Mount.
|
||||||
|
func (m *Mount) ToOCI() spec.Mount {
|
||||||
|
return spec.Mount{
|
||||||
|
Source: m.HostPath,
|
||||||
|
Destination: m.ContainerPath,
|
||||||
|
Options: m.Options,
|
||||||
|
Type: m.Type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToOCI returns the opencontainers runtime Spec LinuxDevice for this DeviceNode.
|
||||||
|
func (d *DeviceNode) ToOCI() spec.LinuxDevice {
|
||||||
|
return spec.LinuxDevice{
|
||||||
|
Path: d.Path,
|
||||||
|
Type: d.Type,
|
||||||
|
Major: d.Major,
|
||||||
|
Minor: d.Minor,
|
||||||
|
FileMode: d.FileMode,
|
||||||
|
UID: d.UID,
|
||||||
|
GID: d.GID,
|
||||||
|
}
|
||||||
|
}
|
57
src/runtime/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
generated
vendored
57
src/runtime/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
generated
vendored
@ -12,6 +12,8 @@ type Spec struct {
|
|||||||
Root *Root `json:"root,omitempty"`
|
Root *Root `json:"root,omitempty"`
|
||||||
// Hostname configures the container's hostname.
|
// Hostname configures the container's hostname.
|
||||||
Hostname string `json:"hostname,omitempty"`
|
Hostname string `json:"hostname,omitempty"`
|
||||||
|
// Domainname configures the container's domainname.
|
||||||
|
Domainname string `json:"domainname,omitempty"`
|
||||||
// Mounts configures additional mounts (on top of Root).
|
// Mounts configures additional mounts (on top of Root).
|
||||||
Mounts []Mount `json:"mounts,omitempty"`
|
Mounts []Mount `json:"mounts,omitempty"`
|
||||||
// Hooks configures callbacks for container lifecycle events.
|
// Hooks configures callbacks for container lifecycle events.
|
||||||
@ -117,6 +119,11 @@ type Mount struct {
|
|||||||
Source string `json:"source,omitempty"`
|
Source string `json:"source,omitempty"`
|
||||||
// Options are fstab style mount options.
|
// Options are fstab style mount options.
|
||||||
Options []string `json:"options,omitempty"`
|
Options []string `json:"options,omitempty"`
|
||||||
|
|
||||||
|
// UID/GID mappings used for changing file owners w/o calling chown, fs should support it.
|
||||||
|
// Every mount point could have its own mapping.
|
||||||
|
UIDMappings []LinuxIDMapping `json:"uidMappings,omitempty" platform:"linux"`
|
||||||
|
GIDMappings []LinuxIDMapping `json:"gidMappings,omitempty" platform:"linux"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hook specifies a command that is run at a particular event in the lifecycle of a container
|
// Hook specifies a command that is run at a particular event in the lifecycle of a container
|
||||||
@ -252,8 +259,8 @@ type LinuxInterfacePriority struct {
|
|||||||
Priority uint32 `json:"priority"`
|
Priority uint32 `json:"priority"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// linuxBlockIODevice holds major:minor format supported in blkio cgroup
|
// LinuxBlockIODevice holds major:minor format supported in blkio cgroup
|
||||||
type linuxBlockIODevice struct {
|
type LinuxBlockIODevice struct {
|
||||||
// Major is the device's major number.
|
// Major is the device's major number.
|
||||||
Major int64 `json:"major"`
|
Major int64 `json:"major"`
|
||||||
// Minor is the device's minor number.
|
// Minor is the device's minor number.
|
||||||
@ -262,7 +269,7 @@ type linuxBlockIODevice struct {
|
|||||||
|
|
||||||
// LinuxWeightDevice struct holds a `major:minor weight` pair for weightDevice
|
// LinuxWeightDevice struct holds a `major:minor weight` pair for weightDevice
|
||||||
type LinuxWeightDevice struct {
|
type LinuxWeightDevice struct {
|
||||||
linuxBlockIODevice
|
LinuxBlockIODevice
|
||||||
// Weight is the bandwidth rate for the device.
|
// Weight is the bandwidth rate for the device.
|
||||||
Weight *uint16 `json:"weight,omitempty"`
|
Weight *uint16 `json:"weight,omitempty"`
|
||||||
// LeafWeight is the bandwidth rate for the device while competing with the cgroup's child cgroups, CFQ scheduler only
|
// LeafWeight is the bandwidth rate for the device while competing with the cgroup's child cgroups, CFQ scheduler only
|
||||||
@ -271,7 +278,7 @@ type LinuxWeightDevice struct {
|
|||||||
|
|
||||||
// LinuxThrottleDevice struct holds a `major:minor rate_per_second` pair
|
// LinuxThrottleDevice struct holds a `major:minor rate_per_second` pair
|
||||||
type LinuxThrottleDevice struct {
|
type LinuxThrottleDevice struct {
|
||||||
linuxBlockIODevice
|
LinuxBlockIODevice
|
||||||
// Rate is the IO rate limit per cgroup per device
|
// Rate is the IO rate limit per cgroup per device
|
||||||
Rate uint64 `json:"rate"`
|
Rate uint64 `json:"rate"`
|
||||||
}
|
}
|
||||||
@ -312,6 +319,10 @@ type LinuxMemory struct {
|
|||||||
DisableOOMKiller *bool `json:"disableOOMKiller,omitempty"`
|
DisableOOMKiller *bool `json:"disableOOMKiller,omitempty"`
|
||||||
// Enables hierarchical memory accounting
|
// Enables hierarchical memory accounting
|
||||||
UseHierarchy *bool `json:"useHierarchy,omitempty"`
|
UseHierarchy *bool `json:"useHierarchy,omitempty"`
|
||||||
|
// CheckBeforeUpdate enables checking if a new memory limit is lower
|
||||||
|
// than the current usage during update, and if so, rejecting the new
|
||||||
|
// limit.
|
||||||
|
CheckBeforeUpdate *bool `json:"checkBeforeUpdate,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinuxCPU for Linux cgroup 'cpu' resource management
|
// LinuxCPU for Linux cgroup 'cpu' resource management
|
||||||
@ -320,6 +331,9 @@ type LinuxCPU struct {
|
|||||||
Shares *uint64 `json:"shares,omitempty"`
|
Shares *uint64 `json:"shares,omitempty"`
|
||||||
// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
|
// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
|
||||||
Quota *int64 `json:"quota,omitempty"`
|
Quota *int64 `json:"quota,omitempty"`
|
||||||
|
// CPU hardcap burst limit (in usecs). Allowed accumulated cpu time additionally for burst in a
|
||||||
|
// given period.
|
||||||
|
Burst *uint64 `json:"burst,omitempty"`
|
||||||
// CPU period to be used for hardcapping (in usecs).
|
// CPU period to be used for hardcapping (in usecs).
|
||||||
Period *uint64 `json:"period,omitempty"`
|
Period *uint64 `json:"period,omitempty"`
|
||||||
// How much time realtime scheduling may use (in usecs).
|
// How much time realtime scheduling may use (in usecs).
|
||||||
@ -330,6 +344,8 @@ type LinuxCPU struct {
|
|||||||
Cpus string `json:"cpus,omitempty"`
|
Cpus string `json:"cpus,omitempty"`
|
||||||
// List of memory nodes in the cpuset. Default is to use any available memory node.
|
// List of memory nodes in the cpuset. Default is to use any available memory node.
|
||||||
Mems string `json:"mems,omitempty"`
|
Mems string `json:"mems,omitempty"`
|
||||||
|
// cgroups are configured with minimum weight, 0: default behavior, 1: SCHED_IDLE.
|
||||||
|
Idle *int64 `json:"idle,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinuxPids for Linux cgroup 'pids' resource management (Linux 4.3)
|
// LinuxPids for Linux cgroup 'pids' resource management (Linux 4.3)
|
||||||
@ -524,11 +540,21 @@ type WindowsMemoryResources struct {
|
|||||||
|
|
||||||
// WindowsCPUResources contains CPU resource management settings.
|
// WindowsCPUResources contains CPU resource management settings.
|
||||||
type WindowsCPUResources struct {
|
type WindowsCPUResources struct {
|
||||||
// Number of CPUs available to the container.
|
// Count is the number of CPUs available to the container. It represents the
|
||||||
|
// fraction of the configured processor `count` in a container in relation
|
||||||
|
// to the processors available in the host. The fraction ultimately
|
||||||
|
// determines the portion of processor cycles that the threads in a
|
||||||
|
// container can use during each scheduling interval, as the number of
|
||||||
|
// cycles per 10,000 cycles.
|
||||||
Count *uint64 `json:"count,omitempty"`
|
Count *uint64 `json:"count,omitempty"`
|
||||||
// CPU shares (relative weight to other containers with cpu shares).
|
// Shares limits the share of processor time given to the container relative
|
||||||
|
// to other workloads on the processor. The processor `shares` (`weight` at
|
||||||
|
// the platform level) is a value between 0 and 10000.
|
||||||
Shares *uint16 `json:"shares,omitempty"`
|
Shares *uint16 `json:"shares,omitempty"`
|
||||||
// Specifies the portion of processor cycles that this container can use as a percentage times 100.
|
// Maximum determines the portion of processor cycles that the threads in a
|
||||||
|
// container can use during each scheduling interval, as the number of
|
||||||
|
// cycles per 10,000 cycles. Set processor `maximum` to a percentage times
|
||||||
|
// 100.
|
||||||
Maximum *uint16 `json:"maximum,omitempty"`
|
Maximum *uint16 `json:"maximum,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,6 +641,23 @@ type Arch string
|
|||||||
// LinuxSeccompFlag is a flag to pass to seccomp(2).
|
// LinuxSeccompFlag is a flag to pass to seccomp(2).
|
||||||
type LinuxSeccompFlag string
|
type LinuxSeccompFlag string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// LinuxSeccompFlagLog is a seccomp flag to request all returned
|
||||||
|
// actions except SECCOMP_RET_ALLOW to be logged. An administrator may
|
||||||
|
// override this filter flag by preventing specific actions from being
|
||||||
|
// logged via the /proc/sys/kernel/seccomp/actions_logged file. (since
|
||||||
|
// Linux 4.14)
|
||||||
|
LinuxSeccompFlagLog LinuxSeccompFlag = "SECCOMP_FILTER_FLAG_LOG"
|
||||||
|
|
||||||
|
// LinuxSeccompFlagSpecAllow can be used to disable Speculative Store
|
||||||
|
// Bypass mitigation. (since Linux 4.17)
|
||||||
|
LinuxSeccompFlagSpecAllow LinuxSeccompFlag = "SECCOMP_FILTER_FLAG_SPEC_ALLOW"
|
||||||
|
|
||||||
|
// LinuxSeccompFlagWaitKillableRecv can be used to switch to the wait
|
||||||
|
// killable semantics. (since Linux 5.19)
|
||||||
|
LinuxSeccompFlagWaitKillableRecv LinuxSeccompFlag = "SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV"
|
||||||
|
)
|
||||||
|
|
||||||
// Additional architectures permitted to be used for system calls
|
// Additional architectures permitted to be used for system calls
|
||||||
// By default only the native architecture of the kernel is permitted
|
// By default only the native architecture of the kernel is permitted
|
||||||
const (
|
const (
|
||||||
|
6
src/runtime/vendor/github.com/opencontainers/runtime-spec/specs-go/version.go
generated
vendored
6
src/runtime/vendor/github.com/opencontainers/runtime-spec/specs-go/version.go
generated
vendored
@ -6,12 +6,12 @@ const (
|
|||||||
// VersionMajor is for an API incompatible changes
|
// VersionMajor is for an API incompatible changes
|
||||||
VersionMajor = 1
|
VersionMajor = 1
|
||||||
// VersionMinor is for functionality in a backwards-compatible manner
|
// VersionMinor is for functionality in a backwards-compatible manner
|
||||||
VersionMinor = 0
|
VersionMinor = 1
|
||||||
// VersionPatch is for backwards-compatible bug fixes
|
// VersionPatch is for backwards-compatible bug fixes
|
||||||
VersionPatch = 2
|
VersionPatch = 0
|
||||||
|
|
||||||
// VersionDev indicates development branch. Releases will be empty string.
|
// VersionDev indicates development branch. Releases will be empty string.
|
||||||
VersionDev = "-dev"
|
VersionDev = "-rc.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Version is the specification version that the package types support.
|
// Version is the specification version that the package types support.
|
||||||
|
191
src/runtime/vendor/github.com/opencontainers/runtime-tools/LICENSE
generated
vendored
Normal file
191
src/runtime/vendor/github.com/opencontainers/runtime-tools/LICENSE
generated
vendored
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
Copyright 2015 The Linux Foundation.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
194
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/config.go
generated
vendored
Normal file
194
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/config.go
generated
vendored
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
package generate
|
||||||
|
|
||||||
|
import (
|
||||||
|
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (g *Generator) initConfig() {
|
||||||
|
if g.Config == nil {
|
||||||
|
g.Config = &rspec.Spec{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigProcess() {
|
||||||
|
g.initConfig()
|
||||||
|
if g.Config.Process == nil {
|
||||||
|
g.Config.Process = &rspec.Process{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigProcessConsoleSize() {
|
||||||
|
g.initConfigProcess()
|
||||||
|
if g.Config.Process.ConsoleSize == nil {
|
||||||
|
g.Config.Process.ConsoleSize = &rspec.Box{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigProcessCapabilities() {
|
||||||
|
g.initConfigProcess()
|
||||||
|
if g.Config.Process.Capabilities == nil {
|
||||||
|
g.Config.Process.Capabilities = &rspec.LinuxCapabilities{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigRoot() {
|
||||||
|
g.initConfig()
|
||||||
|
if g.Config.Root == nil {
|
||||||
|
g.Config.Root = &rspec.Root{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigAnnotations() {
|
||||||
|
g.initConfig()
|
||||||
|
if g.Config.Annotations == nil {
|
||||||
|
g.Config.Annotations = make(map[string]string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigHooks() {
|
||||||
|
g.initConfig()
|
||||||
|
if g.Config.Hooks == nil {
|
||||||
|
g.Config.Hooks = &rspec.Hooks{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigLinux() {
|
||||||
|
g.initConfig()
|
||||||
|
if g.Config.Linux == nil {
|
||||||
|
g.Config.Linux = &rspec.Linux{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigLinuxIntelRdt() {
|
||||||
|
g.initConfigLinux()
|
||||||
|
if g.Config.Linux.IntelRdt == nil {
|
||||||
|
g.Config.Linux.IntelRdt = &rspec.LinuxIntelRdt{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigLinuxSysctl() {
|
||||||
|
g.initConfigLinux()
|
||||||
|
if g.Config.Linux.Sysctl == nil {
|
||||||
|
g.Config.Linux.Sysctl = make(map[string]string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigLinuxSeccomp() {
|
||||||
|
g.initConfigLinux()
|
||||||
|
if g.Config.Linux.Seccomp == nil {
|
||||||
|
g.Config.Linux.Seccomp = &rspec.LinuxSeccomp{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigLinuxResources() {
|
||||||
|
g.initConfigLinux()
|
||||||
|
if g.Config.Linux.Resources == nil {
|
||||||
|
g.Config.Linux.Resources = &rspec.LinuxResources{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigLinuxResourcesBlockIO() {
|
||||||
|
g.initConfigLinuxResources()
|
||||||
|
if g.Config.Linux.Resources.BlockIO == nil {
|
||||||
|
g.Config.Linux.Resources.BlockIO = &rspec.LinuxBlockIO{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitConfigLinuxResourcesCPU initializes CPU of Linux resources
|
||||||
|
func (g *Generator) InitConfigLinuxResourcesCPU() {
|
||||||
|
g.initConfigLinuxResources()
|
||||||
|
if g.Config.Linux.Resources.CPU == nil {
|
||||||
|
g.Config.Linux.Resources.CPU = &rspec.LinuxCPU{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigLinuxResourcesMemory() {
|
||||||
|
g.initConfigLinuxResources()
|
||||||
|
if g.Config.Linux.Resources.Memory == nil {
|
||||||
|
g.Config.Linux.Resources.Memory = &rspec.LinuxMemory{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigLinuxResourcesNetwork() {
|
||||||
|
g.initConfigLinuxResources()
|
||||||
|
if g.Config.Linux.Resources.Network == nil {
|
||||||
|
g.Config.Linux.Resources.Network = &rspec.LinuxNetwork{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigLinuxResourcesPids() {
|
||||||
|
g.initConfigLinuxResources()
|
||||||
|
if g.Config.Linux.Resources.Pids == nil {
|
||||||
|
g.Config.Linux.Resources.Pids = &rspec.LinuxPids{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigLinuxResourcesUnified() {
|
||||||
|
g.initConfigLinuxResources()
|
||||||
|
if g.Config.Linux.Resources.Unified == nil {
|
||||||
|
g.Config.Linux.Resources.Unified = map[string]string{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigSolaris() {
|
||||||
|
g.initConfig()
|
||||||
|
if g.Config.Solaris == nil {
|
||||||
|
g.Config.Solaris = &rspec.Solaris{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigSolarisCappedCPU() {
|
||||||
|
g.initConfigSolaris()
|
||||||
|
if g.Config.Solaris.CappedCPU == nil {
|
||||||
|
g.Config.Solaris.CappedCPU = &rspec.SolarisCappedCPU{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigSolarisCappedMemory() {
|
||||||
|
g.initConfigSolaris()
|
||||||
|
if g.Config.Solaris.CappedMemory == nil {
|
||||||
|
g.Config.Solaris.CappedMemory = &rspec.SolarisCappedMemory{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigWindows() {
|
||||||
|
g.initConfig()
|
||||||
|
if g.Config.Windows == nil {
|
||||||
|
g.Config.Windows = &rspec.Windows{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigWindowsNetwork() {
|
||||||
|
g.initConfigWindows()
|
||||||
|
if g.Config.Windows.Network == nil {
|
||||||
|
g.Config.Windows.Network = &rspec.WindowsNetwork{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigWindowsHyperV() {
|
||||||
|
g.initConfigWindows()
|
||||||
|
if g.Config.Windows.HyperV == nil {
|
||||||
|
g.Config.Windows.HyperV = &rspec.WindowsHyperV{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigWindowsResources() {
|
||||||
|
g.initConfigWindows()
|
||||||
|
if g.Config.Windows.Resources == nil {
|
||||||
|
g.Config.Windows.Resources = &rspec.WindowsResources{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigWindowsResourcesMemory() {
|
||||||
|
g.initConfigWindowsResources()
|
||||||
|
if g.Config.Windows.Resources.Memory == nil {
|
||||||
|
g.Config.Windows.Resources.Memory = &rspec.WindowsMemoryResources{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Generator) initConfigVM() {
|
||||||
|
g.initConfig()
|
||||||
|
if g.Config.VM == nil {
|
||||||
|
g.Config.VM = &rspec.VM{}
|
||||||
|
}
|
||||||
|
}
|
1874
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/generate.go
generated
vendored
Normal file
1874
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/generate.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go
generated
vendored
Normal file
7
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package seccomp
|
||||||
|
|
||||||
|
const (
|
||||||
|
seccompOverwrite = "overwrite"
|
||||||
|
seccompAppend = "append"
|
||||||
|
nothing = "nothing"
|
||||||
|
)
|
135
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_action.go
generated
vendored
Normal file
135
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_action.go
generated
vendored
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
package seccomp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SyscallOpts contain options for parsing syscall rules
|
||||||
|
type SyscallOpts struct {
|
||||||
|
Action string
|
||||||
|
Syscall string
|
||||||
|
Index string
|
||||||
|
Value string
|
||||||
|
ValueTwo string
|
||||||
|
Operator string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseSyscallFlag takes a SyscallOpts struct and the seccomp configuration
|
||||||
|
// and sets the new syscall rule accordingly
|
||||||
|
func ParseSyscallFlag(args SyscallOpts, config *rspec.LinuxSeccomp) error {
|
||||||
|
var arguments []string
|
||||||
|
if args.Index != "" && args.Value != "" && args.ValueTwo != "" && args.Operator != "" {
|
||||||
|
arguments = []string{args.Action, args.Syscall, args.Index, args.Value,
|
||||||
|
args.ValueTwo, args.Operator}
|
||||||
|
} else {
|
||||||
|
arguments = []string{args.Action, args.Syscall}
|
||||||
|
}
|
||||||
|
|
||||||
|
action, _ := parseAction(arguments[0])
|
||||||
|
if action == config.DefaultAction && args.argsAreEmpty() {
|
||||||
|
// default already set, no need to make changes
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var newSyscall rspec.LinuxSyscall
|
||||||
|
numOfArgs := len(arguments)
|
||||||
|
if numOfArgs == 6 || numOfArgs == 2 {
|
||||||
|
argStruct, err := parseArguments(arguments[1:])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newSyscall = newSyscallStruct(arguments[1], action, argStruct)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("incorrect number of arguments to ParseSyscall: %d", numOfArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
descison, err := decideCourseOfAction(&newSyscall, config.Syscalls)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
delimDescison := strings.Split(descison, ":")
|
||||||
|
|
||||||
|
if delimDescison[0] == seccompAppend {
|
||||||
|
config.Syscalls = append(config.Syscalls, newSyscall)
|
||||||
|
}
|
||||||
|
|
||||||
|
if delimDescison[0] == seccompOverwrite {
|
||||||
|
indexForOverwrite, err := strconv.ParseInt(delimDescison[1], 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
config.Syscalls[indexForOverwrite] = newSyscall
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var actions = map[string]rspec.LinuxSeccompAction{
|
||||||
|
"allow": rspec.ActAllow,
|
||||||
|
"errno": rspec.ActErrno,
|
||||||
|
"kill": rspec.ActKill,
|
||||||
|
"trace": rspec.ActTrace,
|
||||||
|
"trap": rspec.ActTrap,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take passed action, return the SCMP_ACT_<ACTION> version of it
|
||||||
|
func parseAction(action string) (rspec.LinuxSeccompAction, error) {
|
||||||
|
a, ok := actions[action]
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("unrecognized action: %s", action)
|
||||||
|
}
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDefaultAction sets the default action of the seccomp configuration
|
||||||
|
// and then removes any rules that were already specified with this action
|
||||||
|
func ParseDefaultAction(action string, config *rspec.LinuxSeccomp) error {
|
||||||
|
if action == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultAction, err := parseAction(action)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
config.DefaultAction = defaultAction
|
||||||
|
err = RemoveAllMatchingRules(config, defaultAction)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDefaultActionForce simply sets the default action of the seccomp configuration
|
||||||
|
func ParseDefaultActionForce(action string, config *rspec.LinuxSeccomp) error {
|
||||||
|
if action == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultAction, err := parseAction(action)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
config.DefaultAction = defaultAction
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSyscallStruct(name string, action rspec.LinuxSeccompAction, args []rspec.LinuxSeccompArg) rspec.LinuxSyscall {
|
||||||
|
syscallStruct := rspec.LinuxSyscall{
|
||||||
|
Names: []string{name},
|
||||||
|
Action: action,
|
||||||
|
Args: args,
|
||||||
|
}
|
||||||
|
return syscallStruct
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SyscallOpts) argsAreEmpty() bool {
|
||||||
|
return (s.Index == "" &&
|
||||||
|
s.Value == "" &&
|
||||||
|
s.ValueTwo == "" &&
|
||||||
|
s.Operator == "")
|
||||||
|
}
|
55
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_architecture.go
generated
vendored
Normal file
55
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_architecture.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package seccomp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParseArchitectureFlag takes the raw string passed with the --arch flag, parses it
|
||||||
|
// and updates the Seccomp config accordingly
|
||||||
|
func ParseArchitectureFlag(architectureArg string, config *rspec.LinuxSeccomp) error {
|
||||||
|
correctedArch, err := parseArch(architectureArg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldAppend := true
|
||||||
|
for _, alreadySpecified := range config.Architectures {
|
||||||
|
if correctedArch == alreadySpecified {
|
||||||
|
shouldAppend = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if shouldAppend {
|
||||||
|
config.Architectures = append(config.Architectures, correctedArch)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseArch(arch string) (rspec.Arch, error) {
|
||||||
|
arches := map[string]rspec.Arch{
|
||||||
|
"x86": rspec.ArchX86,
|
||||||
|
"amd64": rspec.ArchX86_64,
|
||||||
|
"x32": rspec.ArchX32,
|
||||||
|
"arm": rspec.ArchARM,
|
||||||
|
"arm64": rspec.ArchAARCH64,
|
||||||
|
"mips": rspec.ArchMIPS,
|
||||||
|
"mips64": rspec.ArchMIPS64,
|
||||||
|
"mips64n32": rspec.ArchMIPS64N32,
|
||||||
|
"mipsel": rspec.ArchMIPSEL,
|
||||||
|
"mipsel64": rspec.ArchMIPSEL64,
|
||||||
|
"mipsel64n32": rspec.ArchMIPSEL64N32,
|
||||||
|
"parisc": rspec.ArchPARISC,
|
||||||
|
"parisc64": rspec.ArchPARISC64,
|
||||||
|
"ppc": rspec.ArchPPC,
|
||||||
|
"ppc64": rspec.ArchPPC64,
|
||||||
|
"ppc64le": rspec.ArchPPC64LE,
|
||||||
|
"s390": rspec.ArchS390,
|
||||||
|
"s390x": rspec.ArchS390X,
|
||||||
|
}
|
||||||
|
a, ok := arches[arch]
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("unrecognized architecture: %s", arch)
|
||||||
|
}
|
||||||
|
return a, nil
|
||||||
|
}
|
73
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_arguments.go
generated
vendored
Normal file
73
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_arguments.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package seccomp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
// parseArguments takes a list of arguments (delimArgs). It parses and fills out
|
||||||
|
// the argument information and returns a slice of arg structs
|
||||||
|
func parseArguments(delimArgs []string) ([]rspec.LinuxSeccompArg, error) {
|
||||||
|
nilArgSlice := []rspec.LinuxSeccompArg{}
|
||||||
|
numberOfArgs := len(delimArgs)
|
||||||
|
|
||||||
|
// No parameters passed with syscall
|
||||||
|
if numberOfArgs == 1 {
|
||||||
|
return nilArgSlice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Correct number of parameters passed with syscall
|
||||||
|
if numberOfArgs == 5 {
|
||||||
|
syscallIndex, err := strconv.ParseUint(delimArgs[1], 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nilArgSlice, err
|
||||||
|
}
|
||||||
|
|
||||||
|
syscallValue, err := strconv.ParseUint(delimArgs[2], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nilArgSlice, err
|
||||||
|
}
|
||||||
|
|
||||||
|
syscallValueTwo, err := strconv.ParseUint(delimArgs[3], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nilArgSlice, err
|
||||||
|
}
|
||||||
|
|
||||||
|
syscallOp, err := parseOperator(delimArgs[4])
|
||||||
|
if err != nil {
|
||||||
|
return nilArgSlice, err
|
||||||
|
}
|
||||||
|
|
||||||
|
argStruct := rspec.LinuxSeccompArg{
|
||||||
|
Index: uint(syscallIndex),
|
||||||
|
Value: syscallValue,
|
||||||
|
ValueTwo: syscallValueTwo,
|
||||||
|
Op: syscallOp,
|
||||||
|
}
|
||||||
|
|
||||||
|
argSlice := []rspec.LinuxSeccompArg{}
|
||||||
|
argSlice = append(argSlice, argStruct)
|
||||||
|
return argSlice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nilArgSlice, fmt.Errorf("incorrect number of arguments passed with syscall: %d", numberOfArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseOperator(operator string) (rspec.LinuxSeccompOperator, error) {
|
||||||
|
operators := map[string]rspec.LinuxSeccompOperator{
|
||||||
|
"NE": rspec.OpNotEqual,
|
||||||
|
"LT": rspec.OpLessThan,
|
||||||
|
"LE": rspec.OpLessEqual,
|
||||||
|
"EQ": rspec.OpEqualTo,
|
||||||
|
"GE": rspec.OpGreaterEqual,
|
||||||
|
"GT": rspec.OpGreaterThan,
|
||||||
|
"ME": rspec.OpMaskedEqual,
|
||||||
|
}
|
||||||
|
o, ok := operators[operator]
|
||||||
|
if !ok {
|
||||||
|
return "", fmt.Errorf("unrecognized operator: %s", operator)
|
||||||
|
}
|
||||||
|
return o, nil
|
||||||
|
}
|
52
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_remove.go
generated
vendored
Normal file
52
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_remove.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package seccomp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RemoveAction takes the argument string that was passed with the --remove flag,
|
||||||
|
// parses it, and updates the Seccomp config accordingly
|
||||||
|
func RemoveAction(arguments string, config *rspec.LinuxSeccomp) error {
|
||||||
|
if config == nil {
|
||||||
|
return fmt.Errorf("Cannot remove action from nil Seccomp pointer")
|
||||||
|
}
|
||||||
|
|
||||||
|
syscallsToRemove := strings.Split(arguments, ",")
|
||||||
|
|
||||||
|
for counter, syscallStruct := range config.Syscalls {
|
||||||
|
if reflect.DeepEqual(syscallsToRemove, syscallStruct.Names) {
|
||||||
|
config.Syscalls = append(config.Syscalls[:counter], config.Syscalls[counter+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveAllSeccompRules removes all seccomp syscall rules
|
||||||
|
func RemoveAllSeccompRules(config *rspec.LinuxSeccomp) error {
|
||||||
|
if config == nil {
|
||||||
|
return fmt.Errorf("Cannot remove action from nil Seccomp pointer")
|
||||||
|
}
|
||||||
|
newSyscallSlice := []rspec.LinuxSyscall{}
|
||||||
|
config.Syscalls = newSyscallSlice
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveAllMatchingRules will remove any syscall rules that match the specified action
|
||||||
|
func RemoveAllMatchingRules(config *rspec.LinuxSeccomp, seccompAction rspec.LinuxSeccompAction) error {
|
||||||
|
if config == nil {
|
||||||
|
return fmt.Errorf("Cannot remove action from nil Seccomp pointer")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, syscall := range config.Syscalls {
|
||||||
|
if reflect.DeepEqual(syscall.Action, seccompAction) {
|
||||||
|
RemoveAction(strings.Join(syscall.Names, ","), config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
606
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go
generated
vendored
Normal file
606
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go
generated
vendored
Normal file
@ -0,0 +1,606 @@
|
|||||||
|
package seccomp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
func arches() []rspec.Arch {
|
||||||
|
native := runtime.GOARCH
|
||||||
|
|
||||||
|
switch native {
|
||||||
|
case "amd64":
|
||||||
|
return []rspec.Arch{rspec.ArchX86_64, rspec.ArchX86, rspec.ArchX32}
|
||||||
|
case "arm64":
|
||||||
|
return []rspec.Arch{rspec.ArchARM, rspec.ArchAARCH64}
|
||||||
|
case "mips64":
|
||||||
|
return []rspec.Arch{rspec.ArchMIPS, rspec.ArchMIPS64, rspec.ArchMIPS64N32}
|
||||||
|
case "mips64n32":
|
||||||
|
return []rspec.Arch{rspec.ArchMIPS, rspec.ArchMIPS64, rspec.ArchMIPS64N32}
|
||||||
|
case "mipsel64":
|
||||||
|
return []rspec.Arch{rspec.ArchMIPSEL, rspec.ArchMIPSEL64, rspec.ArchMIPSEL64N32}
|
||||||
|
case "mipsel64n32":
|
||||||
|
return []rspec.Arch{rspec.ArchMIPSEL, rspec.ArchMIPSEL64, rspec.ArchMIPSEL64N32}
|
||||||
|
case "s390x":
|
||||||
|
return []rspec.Arch{rspec.ArchS390, rspec.ArchS390X}
|
||||||
|
default:
|
||||||
|
return []rspec.Arch{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultProfile defines the whitelist for the default seccomp profile.
|
||||||
|
func DefaultProfile(rs *specs.Spec) *rspec.LinuxSeccomp {
|
||||||
|
|
||||||
|
syscalls := []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{
|
||||||
|
"accept",
|
||||||
|
"accept4",
|
||||||
|
"access",
|
||||||
|
"alarm",
|
||||||
|
"bind",
|
||||||
|
"brk",
|
||||||
|
"capget",
|
||||||
|
"capset",
|
||||||
|
"chdir",
|
||||||
|
"chmod",
|
||||||
|
"chown",
|
||||||
|
"chown32",
|
||||||
|
"clock_getres",
|
||||||
|
"clock_gettime",
|
||||||
|
"clock_nanosleep",
|
||||||
|
"close",
|
||||||
|
"connect",
|
||||||
|
"copy_file_range",
|
||||||
|
"creat",
|
||||||
|
"dup",
|
||||||
|
"dup2",
|
||||||
|
"dup3",
|
||||||
|
"epoll_create",
|
||||||
|
"epoll_create1",
|
||||||
|
"epoll_ctl",
|
||||||
|
"epoll_ctl_old",
|
||||||
|
"epoll_pwait",
|
||||||
|
"epoll_wait",
|
||||||
|
"epoll_wait_old",
|
||||||
|
"eventfd",
|
||||||
|
"eventfd2",
|
||||||
|
"execve",
|
||||||
|
"execveat",
|
||||||
|
"exit",
|
||||||
|
"exit_group",
|
||||||
|
"faccessat",
|
||||||
|
"fadvise64",
|
||||||
|
"fadvise64_64",
|
||||||
|
"fallocate",
|
||||||
|
"fanotify_mark",
|
||||||
|
"fchdir",
|
||||||
|
"fchmod",
|
||||||
|
"fchmodat",
|
||||||
|
"fchown",
|
||||||
|
"fchown32",
|
||||||
|
"fchownat",
|
||||||
|
"fcntl",
|
||||||
|
"fcntl64",
|
||||||
|
"fdatasync",
|
||||||
|
"fgetxattr",
|
||||||
|
"flistxattr",
|
||||||
|
"flock",
|
||||||
|
"fork",
|
||||||
|
"fremovexattr",
|
||||||
|
"fsetxattr",
|
||||||
|
"fstat",
|
||||||
|
"fstat64",
|
||||||
|
"fstatat64",
|
||||||
|
"fstatfs",
|
||||||
|
"fstatfs64",
|
||||||
|
"fsync",
|
||||||
|
"ftruncate",
|
||||||
|
"ftruncate64",
|
||||||
|
"futex",
|
||||||
|
"futimesat",
|
||||||
|
"getcpu",
|
||||||
|
"getcwd",
|
||||||
|
"getdents",
|
||||||
|
"getdents64",
|
||||||
|
"getegid",
|
||||||
|
"getegid32",
|
||||||
|
"geteuid",
|
||||||
|
"geteuid32",
|
||||||
|
"getgid",
|
||||||
|
"getgid32",
|
||||||
|
"getgroups",
|
||||||
|
"getgroups32",
|
||||||
|
"getitimer",
|
||||||
|
"getpeername",
|
||||||
|
"getpgid",
|
||||||
|
"getpgrp",
|
||||||
|
"getpid",
|
||||||
|
"getppid",
|
||||||
|
"getpriority",
|
||||||
|
"getrandom",
|
||||||
|
"getresgid",
|
||||||
|
"getresgid32",
|
||||||
|
"getresuid",
|
||||||
|
"getresuid32",
|
||||||
|
"getrlimit",
|
||||||
|
"get_robust_list",
|
||||||
|
"getrusage",
|
||||||
|
"getsid",
|
||||||
|
"getsockname",
|
||||||
|
"getsockopt",
|
||||||
|
"get_thread_area",
|
||||||
|
"gettid",
|
||||||
|
"gettimeofday",
|
||||||
|
"getuid",
|
||||||
|
"getuid32",
|
||||||
|
"getxattr",
|
||||||
|
"inotify_add_watch",
|
||||||
|
"inotify_init",
|
||||||
|
"inotify_init1",
|
||||||
|
"inotify_rm_watch",
|
||||||
|
"io_cancel",
|
||||||
|
"ioctl",
|
||||||
|
"io_destroy",
|
||||||
|
"io_getevents",
|
||||||
|
"ioprio_get",
|
||||||
|
"ioprio_set",
|
||||||
|
"io_setup",
|
||||||
|
"io_submit",
|
||||||
|
"ipc",
|
||||||
|
"kill",
|
||||||
|
"landlock_add_rule",
|
||||||
|
"landlock_create_ruleset",
|
||||||
|
"landlock_restrict_self",
|
||||||
|
"lchown",
|
||||||
|
"lchown32",
|
||||||
|
"lgetxattr",
|
||||||
|
"link",
|
||||||
|
"linkat",
|
||||||
|
"listen",
|
||||||
|
"listxattr",
|
||||||
|
"llistxattr",
|
||||||
|
"_llseek",
|
||||||
|
"lremovexattr",
|
||||||
|
"lseek",
|
||||||
|
"lsetxattr",
|
||||||
|
"lstat",
|
||||||
|
"lstat64",
|
||||||
|
"madvise",
|
||||||
|
"memfd_create",
|
||||||
|
"mincore",
|
||||||
|
"mkdir",
|
||||||
|
"mkdirat",
|
||||||
|
"mknod",
|
||||||
|
"mknodat",
|
||||||
|
"mlock",
|
||||||
|
"mlock2",
|
||||||
|
"mlockall",
|
||||||
|
"mmap",
|
||||||
|
"mmap2",
|
||||||
|
"mprotect",
|
||||||
|
"mq_getsetattr",
|
||||||
|
"mq_notify",
|
||||||
|
"mq_open",
|
||||||
|
"mq_timedreceive",
|
||||||
|
"mq_timedsend",
|
||||||
|
"mq_unlink",
|
||||||
|
"mremap",
|
||||||
|
"msgctl",
|
||||||
|
"msgget",
|
||||||
|
"msgrcv",
|
||||||
|
"msgsnd",
|
||||||
|
"msync",
|
||||||
|
"munlock",
|
||||||
|
"munlockall",
|
||||||
|
"munmap",
|
||||||
|
"nanosleep",
|
||||||
|
"newfstatat",
|
||||||
|
"_newselect",
|
||||||
|
"open",
|
||||||
|
"openat",
|
||||||
|
"pause",
|
||||||
|
"pipe",
|
||||||
|
"pipe2",
|
||||||
|
"poll",
|
||||||
|
"ppoll",
|
||||||
|
"prctl",
|
||||||
|
"pread64",
|
||||||
|
"preadv",
|
||||||
|
"prlimit64",
|
||||||
|
"pselect6",
|
||||||
|
"pwrite64",
|
||||||
|
"pwritev",
|
||||||
|
"read",
|
||||||
|
"readahead",
|
||||||
|
"readlink",
|
||||||
|
"readlinkat",
|
||||||
|
"readv",
|
||||||
|
"recv",
|
||||||
|
"recvfrom",
|
||||||
|
"recvmmsg",
|
||||||
|
"recvmsg",
|
||||||
|
"remap_file_pages",
|
||||||
|
"removexattr",
|
||||||
|
"rename",
|
||||||
|
"renameat",
|
||||||
|
"renameat2",
|
||||||
|
"restart_syscall",
|
||||||
|
"rmdir",
|
||||||
|
"rt_sigaction",
|
||||||
|
"rt_sigpending",
|
||||||
|
"rt_sigprocmask",
|
||||||
|
"rt_sigqueueinfo",
|
||||||
|
"rt_sigreturn",
|
||||||
|
"rt_sigsuspend",
|
||||||
|
"rt_sigtimedwait",
|
||||||
|
"rt_tgsigqueueinfo",
|
||||||
|
"sched_getaffinity",
|
||||||
|
"sched_getattr",
|
||||||
|
"sched_getparam",
|
||||||
|
"sched_get_priority_max",
|
||||||
|
"sched_get_priority_min",
|
||||||
|
"sched_getscheduler",
|
||||||
|
"sched_rr_get_interval",
|
||||||
|
"sched_setaffinity",
|
||||||
|
"sched_setattr",
|
||||||
|
"sched_setparam",
|
||||||
|
"sched_setscheduler",
|
||||||
|
"sched_yield",
|
||||||
|
"seccomp",
|
||||||
|
"select",
|
||||||
|
"semctl",
|
||||||
|
"semget",
|
||||||
|
"semop",
|
||||||
|
"semtimedop",
|
||||||
|
"send",
|
||||||
|
"sendfile",
|
||||||
|
"sendfile64",
|
||||||
|
"sendmmsg",
|
||||||
|
"sendmsg",
|
||||||
|
"sendto",
|
||||||
|
"setfsgid",
|
||||||
|
"setfsgid32",
|
||||||
|
"setfsuid",
|
||||||
|
"setfsuid32",
|
||||||
|
"setgid",
|
||||||
|
"setgid32",
|
||||||
|
"setgroups",
|
||||||
|
"setgroups32",
|
||||||
|
"setitimer",
|
||||||
|
"setpgid",
|
||||||
|
"setpriority",
|
||||||
|
"setregid",
|
||||||
|
"setregid32",
|
||||||
|
"setresgid",
|
||||||
|
"setresgid32",
|
||||||
|
"setresuid",
|
||||||
|
"setresuid32",
|
||||||
|
"setreuid",
|
||||||
|
"setreuid32",
|
||||||
|
"setrlimit",
|
||||||
|
"set_robust_list",
|
||||||
|
"setsid",
|
||||||
|
"setsockopt",
|
||||||
|
"set_thread_area",
|
||||||
|
"set_tid_address",
|
||||||
|
"setuid",
|
||||||
|
"setuid32",
|
||||||
|
"setxattr",
|
||||||
|
"shmat",
|
||||||
|
"shmctl",
|
||||||
|
"shmdt",
|
||||||
|
"shmget",
|
||||||
|
"shutdown",
|
||||||
|
"sigaltstack",
|
||||||
|
"signalfd",
|
||||||
|
"signalfd4",
|
||||||
|
"sigreturn",
|
||||||
|
"socket",
|
||||||
|
"socketcall",
|
||||||
|
"socketpair",
|
||||||
|
"splice",
|
||||||
|
"stat",
|
||||||
|
"stat64",
|
||||||
|
"statfs",
|
||||||
|
"statfs64",
|
||||||
|
"statx",
|
||||||
|
"symlink",
|
||||||
|
"symlinkat",
|
||||||
|
"sync",
|
||||||
|
"sync_file_range",
|
||||||
|
"syncfs",
|
||||||
|
"sysinfo",
|
||||||
|
"syslog",
|
||||||
|
"tee",
|
||||||
|
"tgkill",
|
||||||
|
"time",
|
||||||
|
"timer_create",
|
||||||
|
"timer_delete",
|
||||||
|
"timerfd_create",
|
||||||
|
"timerfd_gettime",
|
||||||
|
"timerfd_settime",
|
||||||
|
"timer_getoverrun",
|
||||||
|
"timer_gettime",
|
||||||
|
"timer_settime",
|
||||||
|
"times",
|
||||||
|
"tkill",
|
||||||
|
"truncate",
|
||||||
|
"truncate64",
|
||||||
|
"ugetrlimit",
|
||||||
|
"umask",
|
||||||
|
"uname",
|
||||||
|
"unlink",
|
||||||
|
"unlinkat",
|
||||||
|
"utime",
|
||||||
|
"utimensat",
|
||||||
|
"utimes",
|
||||||
|
"vfork",
|
||||||
|
"vmsplice",
|
||||||
|
"wait4",
|
||||||
|
"waitid",
|
||||||
|
"waitpid",
|
||||||
|
"write",
|
||||||
|
"writev",
|
||||||
|
},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Names: []string{"personality"},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{
|
||||||
|
{
|
||||||
|
Index: 0,
|
||||||
|
Value: 0x0,
|
||||||
|
Op: rspec.OpEqualTo,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Names: []string{"personality"},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{
|
||||||
|
{
|
||||||
|
Index: 0,
|
||||||
|
Value: 0x0008,
|
||||||
|
Op: rspec.OpEqualTo,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Names: []string{"personality"},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{
|
||||||
|
{
|
||||||
|
Index: 0,
|
||||||
|
Value: 0xffffffff,
|
||||||
|
Op: rspec.OpEqualTo,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
var sysCloneFlagsIndex uint
|
||||||
|
|
||||||
|
capSysAdmin := false
|
||||||
|
caps := make(map[string]bool)
|
||||||
|
|
||||||
|
for _, cap := range rs.Process.Capabilities.Bounding {
|
||||||
|
caps[cap] = true
|
||||||
|
}
|
||||||
|
for _, cap := range rs.Process.Capabilities.Effective {
|
||||||
|
caps[cap] = true
|
||||||
|
}
|
||||||
|
for _, cap := range rs.Process.Capabilities.Inheritable {
|
||||||
|
caps[cap] = true
|
||||||
|
}
|
||||||
|
for _, cap := range rs.Process.Capabilities.Permitted {
|
||||||
|
caps[cap] = true
|
||||||
|
}
|
||||||
|
for _, cap := range rs.Process.Capabilities.Ambient {
|
||||||
|
caps[cap] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for cap := range caps {
|
||||||
|
switch cap {
|
||||||
|
case "CAP_DAC_READ_SEARCH":
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{"open_by_handle_at"},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
case "CAP_SYS_ADMIN":
|
||||||
|
capSysAdmin = true
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{
|
||||||
|
"bpf",
|
||||||
|
"clone",
|
||||||
|
"fanotify_init",
|
||||||
|
"lookup_dcookie",
|
||||||
|
"mount",
|
||||||
|
"name_to_handle_at",
|
||||||
|
"perf_event_open",
|
||||||
|
"setdomainname",
|
||||||
|
"sethostname",
|
||||||
|
"setns",
|
||||||
|
"umount",
|
||||||
|
"umount2",
|
||||||
|
"unshare",
|
||||||
|
},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
case "CAP_SYS_BOOT":
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{"reboot"},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
case "CAP_SYS_CHROOT":
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{"chroot"},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
case "CAP_SYS_MODULE":
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{
|
||||||
|
"delete_module",
|
||||||
|
"init_module",
|
||||||
|
"finit_module",
|
||||||
|
"query_module",
|
||||||
|
},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
case "CAP_SYS_PACCT":
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{"acct"},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
case "CAP_SYS_PTRACE":
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{
|
||||||
|
"kcmp",
|
||||||
|
"process_vm_readv",
|
||||||
|
"process_vm_writev",
|
||||||
|
"ptrace",
|
||||||
|
},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
case "CAP_SYS_RAWIO":
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{
|
||||||
|
"iopl",
|
||||||
|
"ioperm",
|
||||||
|
},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
case "CAP_SYS_TIME":
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{
|
||||||
|
"settimeofday",
|
||||||
|
"stime",
|
||||||
|
"adjtimex",
|
||||||
|
},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
case "CAP_SYS_TTY_CONFIG":
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{"vhangup"},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !capSysAdmin {
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{"clone"},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{
|
||||||
|
{
|
||||||
|
Index: sysCloneFlagsIndex,
|
||||||
|
Value: CloneNewNS | CloneNewUTS | CloneNewIPC | CloneNewUser | CloneNewPID | CloneNewNet | CloneNewCgroup,
|
||||||
|
ValueTwo: 0,
|
||||||
|
Op: rspec.OpMaskedEqual,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
arch := runtime.GOARCH
|
||||||
|
switch arch {
|
||||||
|
case "arm", "arm64":
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{
|
||||||
|
"breakpoint",
|
||||||
|
"cacheflush",
|
||||||
|
"set_tls",
|
||||||
|
},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
case "amd64", "x32":
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{"arch_prctl"},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
fallthrough
|
||||||
|
case "x86":
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{"modify_ldt"},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
case "s390", "s390x":
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{
|
||||||
|
"s390_pci_mmio_read",
|
||||||
|
"s390_pci_mmio_write",
|
||||||
|
"s390_runtime_instr",
|
||||||
|
},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
/* Flags parameter of the clone syscall is the 2nd on s390 */
|
||||||
|
syscalls = append(syscalls, []rspec.LinuxSyscall{
|
||||||
|
{
|
||||||
|
Names: []string{"clone"},
|
||||||
|
Action: rspec.ActAllow,
|
||||||
|
Args: []rspec.LinuxSeccompArg{
|
||||||
|
{
|
||||||
|
Index: 1,
|
||||||
|
Value: 2080505856,
|
||||||
|
ValueTwo: 0,
|
||||||
|
Op: rspec.OpMaskedEqual,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &rspec.LinuxSeccomp{
|
||||||
|
DefaultAction: rspec.ActErrno,
|
||||||
|
Architectures: arches(),
|
||||||
|
Syscalls: syscalls,
|
||||||
|
}
|
||||||
|
}
|
17
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_linux.go
generated
vendored
Normal file
17
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_linux.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//go:build linux
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package seccomp
|
||||||
|
|
||||||
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
|
// System values passed through on linux
|
||||||
|
const (
|
||||||
|
CloneNewIPC = unix.CLONE_NEWIPC
|
||||||
|
CloneNewNet = unix.CLONE_NEWNET
|
||||||
|
CloneNewNS = unix.CLONE_NEWNS
|
||||||
|
CloneNewPID = unix.CLONE_NEWPID
|
||||||
|
CloneNewUser = unix.CLONE_NEWUSER
|
||||||
|
CloneNewUTS = unix.CLONE_NEWUTS
|
||||||
|
CloneNewCgroup = unix.CLONE_NEWCGROUP
|
||||||
|
)
|
16
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_unsupported.go
generated
vendored
Normal file
16
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
//go:build !linux
|
||||||
|
// +build !linux
|
||||||
|
|
||||||
|
package seccomp
|
||||||
|
|
||||||
|
// These are copied from linux/amd64 syscall values, as a reference for other
|
||||||
|
// platforms to have access to
|
||||||
|
const (
|
||||||
|
CloneNewIPC = 0x8000000
|
||||||
|
CloneNewNet = 0x40000000
|
||||||
|
CloneNewNS = 0x20000
|
||||||
|
CloneNewPID = 0x20000000
|
||||||
|
CloneNewUser = 0x10000000
|
||||||
|
CloneNewUTS = 0x4000000
|
||||||
|
CloneNewCgroup = 0x02000000
|
||||||
|
)
|
124
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/syscall_compare.go
generated
vendored
Normal file
124
src/runtime/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/syscall_compare.go
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
package seccomp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Determine if a new syscall rule should be appended, overwrite an existing rule
|
||||||
|
// or if no action should be taken at all
|
||||||
|
func decideCourseOfAction(newSyscall *rspec.LinuxSyscall, syscalls []rspec.LinuxSyscall) (string, error) {
|
||||||
|
ruleForSyscallAlreadyExists := false
|
||||||
|
|
||||||
|
var sliceOfDeterminedActions []string
|
||||||
|
for i, syscall := range syscalls {
|
||||||
|
if sameName(&syscall, newSyscall) {
|
||||||
|
ruleForSyscallAlreadyExists = true
|
||||||
|
|
||||||
|
if identical(newSyscall, &syscall) {
|
||||||
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, nothing)
|
||||||
|
}
|
||||||
|
|
||||||
|
if sameAction(newSyscall, &syscall) {
|
||||||
|
if bothHaveArgs(newSyscall, &syscall) {
|
||||||
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend)
|
||||||
|
}
|
||||||
|
if onlyOneHasArgs(newSyscall, &syscall) {
|
||||||
|
if firstParamOnlyHasArgs(newSyscall, &syscall) {
|
||||||
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, "overwrite:"+strconv.Itoa(i))
|
||||||
|
} else {
|
||||||
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, nothing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !sameAction(newSyscall, &syscall) {
|
||||||
|
if bothHaveArgs(newSyscall, &syscall) {
|
||||||
|
if sameArgs(newSyscall, &syscall) {
|
||||||
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, "overwrite:"+strconv.Itoa(i))
|
||||||
|
}
|
||||||
|
if !sameArgs(newSyscall, &syscall) {
|
||||||
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if onlyOneHasArgs(newSyscall, &syscall) {
|
||||||
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend)
|
||||||
|
}
|
||||||
|
if neitherHasArgs(newSyscall, &syscall) {
|
||||||
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, "overwrite:"+strconv.Itoa(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ruleForSyscallAlreadyExists {
|
||||||
|
sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing has highest priority
|
||||||
|
for _, determinedAction := range sliceOfDeterminedActions {
|
||||||
|
if determinedAction == nothing {
|
||||||
|
return determinedAction, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overwrite has second highest priority
|
||||||
|
for _, determinedAction := range sliceOfDeterminedActions {
|
||||||
|
if strings.Contains(determinedAction, seccompOverwrite) {
|
||||||
|
return determinedAction, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append has the lowest priority
|
||||||
|
for _, determinedAction := range sliceOfDeterminedActions {
|
||||||
|
if determinedAction == seccompAppend {
|
||||||
|
return determinedAction, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", fmt.Errorf("Trouble determining action: %s", sliceOfDeterminedActions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasArguments(config *rspec.LinuxSyscall) bool {
|
||||||
|
nilSyscall := new(rspec.LinuxSyscall)
|
||||||
|
return !sameArgs(nilSyscall, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
func identical(config1, config2 *rspec.LinuxSyscall) bool {
|
||||||
|
return reflect.DeepEqual(config1, config2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sameName(config1, config2 *rspec.LinuxSyscall) bool {
|
||||||
|
return reflect.DeepEqual(config1.Names, config2.Names)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sameAction(config1, config2 *rspec.LinuxSyscall) bool {
|
||||||
|
return config1.Action == config2.Action
|
||||||
|
}
|
||||||
|
|
||||||
|
func sameArgs(config1, config2 *rspec.LinuxSyscall) bool {
|
||||||
|
return reflect.DeepEqual(config1.Args, config2.Args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func bothHaveArgs(config1, config2 *rspec.LinuxSyscall) bool {
|
||||||
|
return hasArguments(config1) && hasArguments(config2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func onlyOneHasArgs(config1, config2 *rspec.LinuxSyscall) bool {
|
||||||
|
conf1 := hasArguments(config1)
|
||||||
|
conf2 := hasArguments(config2)
|
||||||
|
|
||||||
|
return (conf1 && !conf2) || (!conf1 && conf2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func neitherHasArgs(config1, config2 *rspec.LinuxSyscall) bool {
|
||||||
|
return !hasArguments(config1) && !hasArguments(config2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func firstParamOnlyHasArgs(config1, config2 *rspec.LinuxSyscall) bool {
|
||||||
|
return !hasArguments(config1) && hasArguments(config2)
|
||||||
|
}
|
31
src/runtime/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate.go
generated
vendored
Normal file
31
src/runtime/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package capabilities
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/syndtr/gocapability/capability"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CapValid checks whether a capability is valid
|
||||||
|
func CapValid(c string, hostSpecific bool) error {
|
||||||
|
isValid := false
|
||||||
|
|
||||||
|
if !strings.HasPrefix(c, "CAP_") {
|
||||||
|
return fmt.Errorf("capability %s must start with CAP_", c)
|
||||||
|
}
|
||||||
|
for _, cap := range capability.List() {
|
||||||
|
if c == fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String())) {
|
||||||
|
if hostSpecific && cap > LastCap() {
|
||||||
|
return fmt.Errorf("%s is not supported on the current host", c)
|
||||||
|
}
|
||||||
|
isValid = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isValid {
|
||||||
|
return fmt.Errorf("invalid capability: %s", c)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
16
src/runtime/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate_linux.go
generated
vendored
Normal file
16
src/runtime/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate_linux.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package capabilities
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/syndtr/gocapability/capability"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LastCap return last cap of system
|
||||||
|
func LastCap() capability.Cap {
|
||||||
|
last := capability.CAP_LAST_CAP
|
||||||
|
// hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
|
||||||
|
if last == capability.Cap(63) {
|
||||||
|
last = capability.CAP_BLOCK_SUSPEND
|
||||||
|
}
|
||||||
|
|
||||||
|
return last
|
||||||
|
}
|
13
src/runtime/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate_unsupported.go
generated
vendored
Normal file
13
src/runtime/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//go:build !linux
|
||||||
|
// +build !linux
|
||||||
|
|
||||||
|
package capabilities
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/syndtr/gocapability/capability"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LastCap return last cap of system
|
||||||
|
func LastCap() capability.Cap {
|
||||||
|
return capability.Cap(-1)
|
||||||
|
}
|
24
src/runtime/vendor/github.com/syndtr/gocapability/LICENSE
generated
vendored
Normal file
24
src/runtime/vendor/github.com/syndtr/gocapability/LICENSE
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
Copyright 2013 Suryandaru Triandana <syndtr@gmail.com>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
133
src/runtime/vendor/github.com/syndtr/gocapability/capability/capability.go
generated
vendored
Normal file
133
src/runtime/vendor/github.com/syndtr/gocapability/capability/capability.go
generated
vendored
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package capability provides utilities for manipulating POSIX capabilities.
|
||||||
|
package capability
|
||||||
|
|
||||||
|
type Capabilities interface {
|
||||||
|
// Get check whether a capability present in the given
|
||||||
|
// capabilities set. The 'which' value should be one of EFFECTIVE,
|
||||||
|
// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
|
||||||
|
Get(which CapType, what Cap) bool
|
||||||
|
|
||||||
|
// Empty check whether all capability bits of the given capabilities
|
||||||
|
// set are zero. The 'which' value should be one of EFFECTIVE,
|
||||||
|
// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
|
||||||
|
Empty(which CapType) bool
|
||||||
|
|
||||||
|
// Full check whether all capability bits of the given capabilities
|
||||||
|
// set are one. The 'which' value should be one of EFFECTIVE,
|
||||||
|
// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
|
||||||
|
Full(which CapType) bool
|
||||||
|
|
||||||
|
// Set sets capabilities of the given capabilities sets. The
|
||||||
|
// 'which' value should be one or combination (OR'ed) of EFFECTIVE,
|
||||||
|
// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
|
||||||
|
Set(which CapType, caps ...Cap)
|
||||||
|
|
||||||
|
// Unset unsets capabilities of the given capabilities sets. The
|
||||||
|
// 'which' value should be one or combination (OR'ed) of EFFECTIVE,
|
||||||
|
// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
|
||||||
|
Unset(which CapType, caps ...Cap)
|
||||||
|
|
||||||
|
// Fill sets all bits of the given capabilities kind to one. The
|
||||||
|
// 'kind' value should be one or combination (OR'ed) of CAPS,
|
||||||
|
// BOUNDS or AMBS.
|
||||||
|
Fill(kind CapType)
|
||||||
|
|
||||||
|
// Clear sets all bits of the given capabilities kind to zero. The
|
||||||
|
// 'kind' value should be one or combination (OR'ed) of CAPS,
|
||||||
|
// BOUNDS or AMBS.
|
||||||
|
Clear(kind CapType)
|
||||||
|
|
||||||
|
// String return current capabilities state of the given capabilities
|
||||||
|
// set as string. The 'which' value should be one of EFFECTIVE,
|
||||||
|
// PERMITTED, INHERITABLE BOUNDING or AMBIENT
|
||||||
|
StringCap(which CapType) string
|
||||||
|
|
||||||
|
// String return current capabilities state as string.
|
||||||
|
String() string
|
||||||
|
|
||||||
|
// Load load actual capabilities value. This will overwrite all
|
||||||
|
// outstanding changes.
|
||||||
|
Load() error
|
||||||
|
|
||||||
|
// Apply apply the capabilities settings, so all changes will take
|
||||||
|
// effect.
|
||||||
|
Apply(kind CapType) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPid initializes a new Capabilities object for given pid when
|
||||||
|
// it is nonzero, or for the current process if pid is 0.
|
||||||
|
//
|
||||||
|
// Deprecated: Replace with NewPid2. For example, replace:
|
||||||
|
//
|
||||||
|
// c, err := NewPid(0)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// with:
|
||||||
|
//
|
||||||
|
// c, err := NewPid2(0)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// err = c.Load()
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
func NewPid(pid int) (Capabilities, error) {
|
||||||
|
c, err := newPid(pid)
|
||||||
|
if err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
err = c.Load()
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPid2 initializes a new Capabilities object for given pid when
|
||||||
|
// it is nonzero, or for the current process if pid is 0. This
|
||||||
|
// does not load the process's current capabilities; to do that you
|
||||||
|
// must call Load explicitly.
|
||||||
|
func NewPid2(pid int) (Capabilities, error) {
|
||||||
|
return newPid(pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFile initializes a new Capabilities object for given file path.
|
||||||
|
//
|
||||||
|
// Deprecated: Replace with NewFile2. For example, replace:
|
||||||
|
//
|
||||||
|
// c, err := NewFile(path)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// with:
|
||||||
|
//
|
||||||
|
// c, err := NewFile2(path)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// err = c.Load()
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
func NewFile(path string) (Capabilities, error) {
|
||||||
|
c, err := newFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
err = c.Load()
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFile2 creates a new initialized Capabilities object for given
|
||||||
|
// file path. This does not load the process's current capabilities;
|
||||||
|
// to do that you must call Load explicitly.
|
||||||
|
func NewFile2(path string) (Capabilities, error) {
|
||||||
|
return newFile(path)
|
||||||
|
}
|
642
src/runtime/vendor/github.com/syndtr/gocapability/capability/capability_linux.go
generated
vendored
Normal file
642
src/runtime/vendor/github.com/syndtr/gocapability/capability/capability_linux.go
generated
vendored
Normal file
@ -0,0 +1,642 @@
|
|||||||
|
// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
package capability
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
var errUnknownVers = errors.New("unknown capability version")
|
||||||
|
|
||||||
|
const (
|
||||||
|
linuxCapVer1 = 0x19980330
|
||||||
|
linuxCapVer2 = 0x20071026
|
||||||
|
linuxCapVer3 = 0x20080522
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
capVers uint32
|
||||||
|
capLastCap Cap
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var hdr capHeader
|
||||||
|
capget(&hdr, nil)
|
||||||
|
capVers = hdr.version
|
||||||
|
|
||||||
|
if initLastCap() == nil {
|
||||||
|
CAP_LAST_CAP = capLastCap
|
||||||
|
if capLastCap > 31 {
|
||||||
|
capUpperMask = (uint32(1) << (uint(capLastCap) - 31)) - 1
|
||||||
|
} else {
|
||||||
|
capUpperMask = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func initLastCap() error {
|
||||||
|
if capLastCap != 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Open("/proc/sys/kernel/cap_last_cap")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
var b []byte = make([]byte, 11)
|
||||||
|
_, err = f.Read(b)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Sscanf(string(b), "%d", &capLastCap)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func mkStringCap(c Capabilities, which CapType) (ret string) {
|
||||||
|
for i, first := Cap(0), true; i <= CAP_LAST_CAP; i++ {
|
||||||
|
if !c.Get(which, i) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if first {
|
||||||
|
first = false
|
||||||
|
} else {
|
||||||
|
ret += ", "
|
||||||
|
}
|
||||||
|
ret += i.String()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func mkString(c Capabilities, max CapType) (ret string) {
|
||||||
|
ret = "{"
|
||||||
|
for i := CapType(1); i <= max; i <<= 1 {
|
||||||
|
ret += " " + i.String() + "=\""
|
||||||
|
if c.Empty(i) {
|
||||||
|
ret += "empty"
|
||||||
|
} else if c.Full(i) {
|
||||||
|
ret += "full"
|
||||||
|
} else {
|
||||||
|
ret += c.StringCap(i)
|
||||||
|
}
|
||||||
|
ret += "\""
|
||||||
|
}
|
||||||
|
ret += " }"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPid(pid int) (c Capabilities, err error) {
|
||||||
|
switch capVers {
|
||||||
|
case linuxCapVer1:
|
||||||
|
p := new(capsV1)
|
||||||
|
p.hdr.version = capVers
|
||||||
|
p.hdr.pid = int32(pid)
|
||||||
|
c = p
|
||||||
|
case linuxCapVer2, linuxCapVer3:
|
||||||
|
p := new(capsV3)
|
||||||
|
p.hdr.version = capVers
|
||||||
|
p.hdr.pid = int32(pid)
|
||||||
|
c = p
|
||||||
|
default:
|
||||||
|
err = errUnknownVers
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type capsV1 struct {
|
||||||
|
hdr capHeader
|
||||||
|
data capData
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV1) Get(which CapType, what Cap) bool {
|
||||||
|
if what > 32 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch which {
|
||||||
|
case EFFECTIVE:
|
||||||
|
return (1<<uint(what))&c.data.effective != 0
|
||||||
|
case PERMITTED:
|
||||||
|
return (1<<uint(what))&c.data.permitted != 0
|
||||||
|
case INHERITABLE:
|
||||||
|
return (1<<uint(what))&c.data.inheritable != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV1) getData(which CapType) (ret uint32) {
|
||||||
|
switch which {
|
||||||
|
case EFFECTIVE:
|
||||||
|
ret = c.data.effective
|
||||||
|
case PERMITTED:
|
||||||
|
ret = c.data.permitted
|
||||||
|
case INHERITABLE:
|
||||||
|
ret = c.data.inheritable
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV1) Empty(which CapType) bool {
|
||||||
|
return c.getData(which) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV1) Full(which CapType) bool {
|
||||||
|
return (c.getData(which) & 0x7fffffff) == 0x7fffffff
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV1) Set(which CapType, caps ...Cap) {
|
||||||
|
for _, what := range caps {
|
||||||
|
if what > 32 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if which&EFFECTIVE != 0 {
|
||||||
|
c.data.effective |= 1 << uint(what)
|
||||||
|
}
|
||||||
|
if which&PERMITTED != 0 {
|
||||||
|
c.data.permitted |= 1 << uint(what)
|
||||||
|
}
|
||||||
|
if which&INHERITABLE != 0 {
|
||||||
|
c.data.inheritable |= 1 << uint(what)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV1) Unset(which CapType, caps ...Cap) {
|
||||||
|
for _, what := range caps {
|
||||||
|
if what > 32 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if which&EFFECTIVE != 0 {
|
||||||
|
c.data.effective &= ^(1 << uint(what))
|
||||||
|
}
|
||||||
|
if which&PERMITTED != 0 {
|
||||||
|
c.data.permitted &= ^(1 << uint(what))
|
||||||
|
}
|
||||||
|
if which&INHERITABLE != 0 {
|
||||||
|
c.data.inheritable &= ^(1 << uint(what))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV1) Fill(kind CapType) {
|
||||||
|
if kind&CAPS == CAPS {
|
||||||
|
c.data.effective = 0x7fffffff
|
||||||
|
c.data.permitted = 0x7fffffff
|
||||||
|
c.data.inheritable = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV1) Clear(kind CapType) {
|
||||||
|
if kind&CAPS == CAPS {
|
||||||
|
c.data.effective = 0
|
||||||
|
c.data.permitted = 0
|
||||||
|
c.data.inheritable = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV1) StringCap(which CapType) (ret string) {
|
||||||
|
return mkStringCap(c, which)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV1) String() (ret string) {
|
||||||
|
return mkString(c, BOUNDING)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV1) Load() (err error) {
|
||||||
|
return capget(&c.hdr, &c.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV1) Apply(kind CapType) error {
|
||||||
|
if kind&CAPS == CAPS {
|
||||||
|
return capset(&c.hdr, &c.data)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type capsV3 struct {
|
||||||
|
hdr capHeader
|
||||||
|
data [2]capData
|
||||||
|
bounds [2]uint32
|
||||||
|
ambient [2]uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV3) Get(which CapType, what Cap) bool {
|
||||||
|
var i uint
|
||||||
|
if what > 31 {
|
||||||
|
i = uint(what) >> 5
|
||||||
|
what %= 32
|
||||||
|
}
|
||||||
|
|
||||||
|
switch which {
|
||||||
|
case EFFECTIVE:
|
||||||
|
return (1<<uint(what))&c.data[i].effective != 0
|
||||||
|
case PERMITTED:
|
||||||
|
return (1<<uint(what))&c.data[i].permitted != 0
|
||||||
|
case INHERITABLE:
|
||||||
|
return (1<<uint(what))&c.data[i].inheritable != 0
|
||||||
|
case BOUNDING:
|
||||||
|
return (1<<uint(what))&c.bounds[i] != 0
|
||||||
|
case AMBIENT:
|
||||||
|
return (1<<uint(what))&c.ambient[i] != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV3) getData(which CapType, dest []uint32) {
|
||||||
|
switch which {
|
||||||
|
case EFFECTIVE:
|
||||||
|
dest[0] = c.data[0].effective
|
||||||
|
dest[1] = c.data[1].effective
|
||||||
|
case PERMITTED:
|
||||||
|
dest[0] = c.data[0].permitted
|
||||||
|
dest[1] = c.data[1].permitted
|
||||||
|
case INHERITABLE:
|
||||||
|
dest[0] = c.data[0].inheritable
|
||||||
|
dest[1] = c.data[1].inheritable
|
||||||
|
case BOUNDING:
|
||||||
|
dest[0] = c.bounds[0]
|
||||||
|
dest[1] = c.bounds[1]
|
||||||
|
case AMBIENT:
|
||||||
|
dest[0] = c.ambient[0]
|
||||||
|
dest[1] = c.ambient[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV3) Empty(which CapType) bool {
|
||||||
|
var data [2]uint32
|
||||||
|
c.getData(which, data[:])
|
||||||
|
return data[0] == 0 && data[1] == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV3) Full(which CapType) bool {
|
||||||
|
var data [2]uint32
|
||||||
|
c.getData(which, data[:])
|
||||||
|
if (data[0] & 0xffffffff) != 0xffffffff {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return (data[1] & capUpperMask) == capUpperMask
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV3) Set(which CapType, caps ...Cap) {
|
||||||
|
for _, what := range caps {
|
||||||
|
var i uint
|
||||||
|
if what > 31 {
|
||||||
|
i = uint(what) >> 5
|
||||||
|
what %= 32
|
||||||
|
}
|
||||||
|
|
||||||
|
if which&EFFECTIVE != 0 {
|
||||||
|
c.data[i].effective |= 1 << uint(what)
|
||||||
|
}
|
||||||
|
if which&PERMITTED != 0 {
|
||||||
|
c.data[i].permitted |= 1 << uint(what)
|
||||||
|
}
|
||||||
|
if which&INHERITABLE != 0 {
|
||||||
|
c.data[i].inheritable |= 1 << uint(what)
|
||||||
|
}
|
||||||
|
if which&BOUNDING != 0 {
|
||||||
|
c.bounds[i] |= 1 << uint(what)
|
||||||
|
}
|
||||||
|
if which&AMBIENT != 0 {
|
||||||
|
c.ambient[i] |= 1 << uint(what)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV3) Unset(which CapType, caps ...Cap) {
|
||||||
|
for _, what := range caps {
|
||||||
|
var i uint
|
||||||
|
if what > 31 {
|
||||||
|
i = uint(what) >> 5
|
||||||
|
what %= 32
|
||||||
|
}
|
||||||
|
|
||||||
|
if which&EFFECTIVE != 0 {
|
||||||
|
c.data[i].effective &= ^(1 << uint(what))
|
||||||
|
}
|
||||||
|
if which&PERMITTED != 0 {
|
||||||
|
c.data[i].permitted &= ^(1 << uint(what))
|
||||||
|
}
|
||||||
|
if which&INHERITABLE != 0 {
|
||||||
|
c.data[i].inheritable &= ^(1 << uint(what))
|
||||||
|
}
|
||||||
|
if which&BOUNDING != 0 {
|
||||||
|
c.bounds[i] &= ^(1 << uint(what))
|
||||||
|
}
|
||||||
|
if which&AMBIENT != 0 {
|
||||||
|
c.ambient[i] &= ^(1 << uint(what))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV3) Fill(kind CapType) {
|
||||||
|
if kind&CAPS == CAPS {
|
||||||
|
c.data[0].effective = 0xffffffff
|
||||||
|
c.data[0].permitted = 0xffffffff
|
||||||
|
c.data[0].inheritable = 0
|
||||||
|
c.data[1].effective = 0xffffffff
|
||||||
|
c.data[1].permitted = 0xffffffff
|
||||||
|
c.data[1].inheritable = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if kind&BOUNDS == BOUNDS {
|
||||||
|
c.bounds[0] = 0xffffffff
|
||||||
|
c.bounds[1] = 0xffffffff
|
||||||
|
}
|
||||||
|
if kind&AMBS == AMBS {
|
||||||
|
c.ambient[0] = 0xffffffff
|
||||||
|
c.ambient[1] = 0xffffffff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV3) Clear(kind CapType) {
|
||||||
|
if kind&CAPS == CAPS {
|
||||||
|
c.data[0].effective = 0
|
||||||
|
c.data[0].permitted = 0
|
||||||
|
c.data[0].inheritable = 0
|
||||||
|
c.data[1].effective = 0
|
||||||
|
c.data[1].permitted = 0
|
||||||
|
c.data[1].inheritable = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if kind&BOUNDS == BOUNDS {
|
||||||
|
c.bounds[0] = 0
|
||||||
|
c.bounds[1] = 0
|
||||||
|
}
|
||||||
|
if kind&AMBS == AMBS {
|
||||||
|
c.ambient[0] = 0
|
||||||
|
c.ambient[1] = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV3) StringCap(which CapType) (ret string) {
|
||||||
|
return mkStringCap(c, which)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV3) String() (ret string) {
|
||||||
|
return mkString(c, BOUNDING)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV3) Load() (err error) {
|
||||||
|
err = capget(&c.hdr, &c.data[0])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var status_path string
|
||||||
|
|
||||||
|
if c.hdr.pid == 0 {
|
||||||
|
status_path = fmt.Sprintf("/proc/self/status")
|
||||||
|
} else {
|
||||||
|
status_path = fmt.Sprintf("/proc/%d/status", c.hdr.pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Open(status_path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b := bufio.NewReader(f)
|
||||||
|
for {
|
||||||
|
line, e := b.ReadString('\n')
|
||||||
|
if e != nil {
|
||||||
|
if e != io.EOF {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(line, "CapB") {
|
||||||
|
fmt.Sscanf(line[4:], "nd: %08x%08x", &c.bounds[1], &c.bounds[0])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(line, "CapA") {
|
||||||
|
fmt.Sscanf(line[4:], "mb: %08x%08x", &c.ambient[1], &c.ambient[0])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.Close()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsV3) Apply(kind CapType) (err error) {
|
||||||
|
if kind&BOUNDS == BOUNDS {
|
||||||
|
var data [2]capData
|
||||||
|
err = capget(&c.hdr, &data[0])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (1<<uint(CAP_SETPCAP))&data[0].effective != 0 {
|
||||||
|
for i := Cap(0); i <= CAP_LAST_CAP; i++ {
|
||||||
|
if c.Get(BOUNDING, i) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
err = prctl(syscall.PR_CAPBSET_DROP, uintptr(i), 0, 0, 0)
|
||||||
|
if err != nil {
|
||||||
|
// Ignore EINVAL since the capability may not be supported in this system.
|
||||||
|
if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINVAL {
|
||||||
|
err = nil
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if kind&CAPS == CAPS {
|
||||||
|
err = capset(&c.hdr, &c.data[0])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if kind&AMBS == AMBS {
|
||||||
|
for i := Cap(0); i <= CAP_LAST_CAP; i++ {
|
||||||
|
action := pr_CAP_AMBIENT_LOWER
|
||||||
|
if c.Get(AMBIENT, i) {
|
||||||
|
action = pr_CAP_AMBIENT_RAISE
|
||||||
|
}
|
||||||
|
err := prctl(pr_CAP_AMBIENT, action, uintptr(i), 0, 0)
|
||||||
|
// Ignore EINVAL as not supported on kernels before 4.3
|
||||||
|
if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINVAL {
|
||||||
|
err = nil
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFile(path string) (c Capabilities, err error) {
|
||||||
|
c = &capsFile{path: path}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type capsFile struct {
|
||||||
|
path string
|
||||||
|
data vfscapData
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsFile) Get(which CapType, what Cap) bool {
|
||||||
|
var i uint
|
||||||
|
if what > 31 {
|
||||||
|
if c.data.version == 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
i = uint(what) >> 5
|
||||||
|
what %= 32
|
||||||
|
}
|
||||||
|
|
||||||
|
switch which {
|
||||||
|
case EFFECTIVE:
|
||||||
|
return (1<<uint(what))&c.data.effective[i] != 0
|
||||||
|
case PERMITTED:
|
||||||
|
return (1<<uint(what))&c.data.data[i].permitted != 0
|
||||||
|
case INHERITABLE:
|
||||||
|
return (1<<uint(what))&c.data.data[i].inheritable != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsFile) getData(which CapType, dest []uint32) {
|
||||||
|
switch which {
|
||||||
|
case EFFECTIVE:
|
||||||
|
dest[0] = c.data.effective[0]
|
||||||
|
dest[1] = c.data.effective[1]
|
||||||
|
case PERMITTED:
|
||||||
|
dest[0] = c.data.data[0].permitted
|
||||||
|
dest[1] = c.data.data[1].permitted
|
||||||
|
case INHERITABLE:
|
||||||
|
dest[0] = c.data.data[0].inheritable
|
||||||
|
dest[1] = c.data.data[1].inheritable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsFile) Empty(which CapType) bool {
|
||||||
|
var data [2]uint32
|
||||||
|
c.getData(which, data[:])
|
||||||
|
return data[0] == 0 && data[1] == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsFile) Full(which CapType) bool {
|
||||||
|
var data [2]uint32
|
||||||
|
c.getData(which, data[:])
|
||||||
|
if c.data.version == 0 {
|
||||||
|
return (data[0] & 0x7fffffff) == 0x7fffffff
|
||||||
|
}
|
||||||
|
if (data[0] & 0xffffffff) != 0xffffffff {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return (data[1] & capUpperMask) == capUpperMask
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsFile) Set(which CapType, caps ...Cap) {
|
||||||
|
for _, what := range caps {
|
||||||
|
var i uint
|
||||||
|
if what > 31 {
|
||||||
|
if c.data.version == 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i = uint(what) >> 5
|
||||||
|
what %= 32
|
||||||
|
}
|
||||||
|
|
||||||
|
if which&EFFECTIVE != 0 {
|
||||||
|
c.data.effective[i] |= 1 << uint(what)
|
||||||
|
}
|
||||||
|
if which&PERMITTED != 0 {
|
||||||
|
c.data.data[i].permitted |= 1 << uint(what)
|
||||||
|
}
|
||||||
|
if which&INHERITABLE != 0 {
|
||||||
|
c.data.data[i].inheritable |= 1 << uint(what)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsFile) Unset(which CapType, caps ...Cap) {
|
||||||
|
for _, what := range caps {
|
||||||
|
var i uint
|
||||||
|
if what > 31 {
|
||||||
|
if c.data.version == 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i = uint(what) >> 5
|
||||||
|
what %= 32
|
||||||
|
}
|
||||||
|
|
||||||
|
if which&EFFECTIVE != 0 {
|
||||||
|
c.data.effective[i] &= ^(1 << uint(what))
|
||||||
|
}
|
||||||
|
if which&PERMITTED != 0 {
|
||||||
|
c.data.data[i].permitted &= ^(1 << uint(what))
|
||||||
|
}
|
||||||
|
if which&INHERITABLE != 0 {
|
||||||
|
c.data.data[i].inheritable &= ^(1 << uint(what))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsFile) Fill(kind CapType) {
|
||||||
|
if kind&CAPS == CAPS {
|
||||||
|
c.data.effective[0] = 0xffffffff
|
||||||
|
c.data.data[0].permitted = 0xffffffff
|
||||||
|
c.data.data[0].inheritable = 0
|
||||||
|
if c.data.version == 2 {
|
||||||
|
c.data.effective[1] = 0xffffffff
|
||||||
|
c.data.data[1].permitted = 0xffffffff
|
||||||
|
c.data.data[1].inheritable = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsFile) Clear(kind CapType) {
|
||||||
|
if kind&CAPS == CAPS {
|
||||||
|
c.data.effective[0] = 0
|
||||||
|
c.data.data[0].permitted = 0
|
||||||
|
c.data.data[0].inheritable = 0
|
||||||
|
if c.data.version == 2 {
|
||||||
|
c.data.effective[1] = 0
|
||||||
|
c.data.data[1].permitted = 0
|
||||||
|
c.data.data[1].inheritable = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsFile) StringCap(which CapType) (ret string) {
|
||||||
|
return mkStringCap(c, which)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsFile) String() (ret string) {
|
||||||
|
return mkString(c, INHERITABLE)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsFile) Load() (err error) {
|
||||||
|
return getVfsCap(c.path, &c.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *capsFile) Apply(kind CapType) (err error) {
|
||||||
|
if kind&CAPS == CAPS {
|
||||||
|
return setVfsCap(c.path, &c.data)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
19
src/runtime/vendor/github.com/syndtr/gocapability/capability/capability_noop.go
generated
vendored
Normal file
19
src/runtime/vendor/github.com/syndtr/gocapability/capability/capability_noop.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !linux
|
||||||
|
|
||||||
|
package capability
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
func newPid(pid int) (Capabilities, error) {
|
||||||
|
return nil, errors.New("not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFile(path string) (Capabilities, error) {
|
||||||
|
return nil, errors.New("not supported")
|
||||||
|
}
|
309
src/runtime/vendor/github.com/syndtr/gocapability/capability/enum.go
generated
vendored
Normal file
309
src/runtime/vendor/github.com/syndtr/gocapability/capability/enum.go
generated
vendored
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
package capability
|
||||||
|
|
||||||
|
type CapType uint
|
||||||
|
|
||||||
|
func (c CapType) String() string {
|
||||||
|
switch c {
|
||||||
|
case EFFECTIVE:
|
||||||
|
return "effective"
|
||||||
|
case PERMITTED:
|
||||||
|
return "permitted"
|
||||||
|
case INHERITABLE:
|
||||||
|
return "inheritable"
|
||||||
|
case BOUNDING:
|
||||||
|
return "bounding"
|
||||||
|
case CAPS:
|
||||||
|
return "caps"
|
||||||
|
case AMBIENT:
|
||||||
|
return "ambient"
|
||||||
|
}
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
EFFECTIVE CapType = 1 << iota
|
||||||
|
PERMITTED
|
||||||
|
INHERITABLE
|
||||||
|
BOUNDING
|
||||||
|
AMBIENT
|
||||||
|
|
||||||
|
CAPS = EFFECTIVE | PERMITTED | INHERITABLE
|
||||||
|
BOUNDS = BOUNDING
|
||||||
|
AMBS = AMBIENT
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:generate go run enumgen/gen.go
|
||||||
|
type Cap int
|
||||||
|
|
||||||
|
// POSIX-draft defined capabilities and Linux extensions.
|
||||||
|
//
|
||||||
|
// Defined in https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h
|
||||||
|
const (
|
||||||
|
// In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this
|
||||||
|
// overrides the restriction of changing file ownership and group
|
||||||
|
// ownership.
|
||||||
|
CAP_CHOWN = Cap(0)
|
||||||
|
|
||||||
|
// Override all DAC access, including ACL execute access if
|
||||||
|
// [_POSIX_ACL] is defined. Excluding DAC access covered by
|
||||||
|
// CAP_LINUX_IMMUTABLE.
|
||||||
|
CAP_DAC_OVERRIDE = Cap(1)
|
||||||
|
|
||||||
|
// Overrides all DAC restrictions regarding read and search on files
|
||||||
|
// and directories, including ACL restrictions if [_POSIX_ACL] is
|
||||||
|
// defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE.
|
||||||
|
CAP_DAC_READ_SEARCH = Cap(2)
|
||||||
|
|
||||||
|
// Overrides all restrictions about allowed operations on files, where
|
||||||
|
// file owner ID must be equal to the user ID, except where CAP_FSETID
|
||||||
|
// is applicable. It doesn't override MAC and DAC restrictions.
|
||||||
|
CAP_FOWNER = Cap(3)
|
||||||
|
|
||||||
|
// Overrides the following restrictions that the effective user ID
|
||||||
|
// shall match the file owner ID when setting the S_ISUID and S_ISGID
|
||||||
|
// bits on that file; that the effective group ID (or one of the
|
||||||
|
// supplementary group IDs) shall match the file owner ID when setting
|
||||||
|
// the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits are
|
||||||
|
// cleared on successful return from chown(2) (not implemented).
|
||||||
|
CAP_FSETID = Cap(4)
|
||||||
|
|
||||||
|
// Overrides the restriction that the real or effective user ID of a
|
||||||
|
// process sending a signal must match the real or effective user ID
|
||||||
|
// of the process receiving the signal.
|
||||||
|
CAP_KILL = Cap(5)
|
||||||
|
|
||||||
|
// Allows setgid(2) manipulation
|
||||||
|
// Allows setgroups(2)
|
||||||
|
// Allows forged gids on socket credentials passing.
|
||||||
|
CAP_SETGID = Cap(6)
|
||||||
|
|
||||||
|
// Allows set*uid(2) manipulation (including fsuid).
|
||||||
|
// Allows forged pids on socket credentials passing.
|
||||||
|
CAP_SETUID = Cap(7)
|
||||||
|
|
||||||
|
// Linux-specific capabilities
|
||||||
|
|
||||||
|
// Without VFS support for capabilities:
|
||||||
|
// Transfer any capability in your permitted set to any pid,
|
||||||
|
// remove any capability in your permitted set from any pid
|
||||||
|
// With VFS support for capabilities (neither of above, but)
|
||||||
|
// Add any capability from current's capability bounding set
|
||||||
|
// to the current process' inheritable set
|
||||||
|
// Allow taking bits out of capability bounding set
|
||||||
|
// Allow modification of the securebits for a process
|
||||||
|
CAP_SETPCAP = Cap(8)
|
||||||
|
|
||||||
|
// Allow modification of S_IMMUTABLE and S_APPEND file attributes
|
||||||
|
CAP_LINUX_IMMUTABLE = Cap(9)
|
||||||
|
|
||||||
|
// Allows binding to TCP/UDP sockets below 1024
|
||||||
|
// Allows binding to ATM VCIs below 32
|
||||||
|
CAP_NET_BIND_SERVICE = Cap(10)
|
||||||
|
|
||||||
|
// Allow broadcasting, listen to multicast
|
||||||
|
CAP_NET_BROADCAST = Cap(11)
|
||||||
|
|
||||||
|
// Allow interface configuration
|
||||||
|
// Allow administration of IP firewall, masquerading and accounting
|
||||||
|
// Allow setting debug option on sockets
|
||||||
|
// Allow modification of routing tables
|
||||||
|
// Allow setting arbitrary process / process group ownership on
|
||||||
|
// sockets
|
||||||
|
// Allow binding to any address for transparent proxying (also via NET_RAW)
|
||||||
|
// Allow setting TOS (type of service)
|
||||||
|
// Allow setting promiscuous mode
|
||||||
|
// Allow clearing driver statistics
|
||||||
|
// Allow multicasting
|
||||||
|
// Allow read/write of device-specific registers
|
||||||
|
// Allow activation of ATM control sockets
|
||||||
|
CAP_NET_ADMIN = Cap(12)
|
||||||
|
|
||||||
|
// Allow use of RAW sockets
|
||||||
|
// Allow use of PACKET sockets
|
||||||
|
// Allow binding to any address for transparent proxying (also via NET_ADMIN)
|
||||||
|
CAP_NET_RAW = Cap(13)
|
||||||
|
|
||||||
|
// Allow locking of shared memory segments
|
||||||
|
// Allow mlock and mlockall (which doesn't really have anything to do
|
||||||
|
// with IPC)
|
||||||
|
CAP_IPC_LOCK = Cap(14)
|
||||||
|
|
||||||
|
// Override IPC ownership checks
|
||||||
|
CAP_IPC_OWNER = Cap(15)
|
||||||
|
|
||||||
|
// Insert and remove kernel modules - modify kernel without limit
|
||||||
|
CAP_SYS_MODULE = Cap(16)
|
||||||
|
|
||||||
|
// Allow ioperm/iopl access
|
||||||
|
// Allow sending USB messages to any device via /proc/bus/usb
|
||||||
|
CAP_SYS_RAWIO = Cap(17)
|
||||||
|
|
||||||
|
// Allow use of chroot()
|
||||||
|
CAP_SYS_CHROOT = Cap(18)
|
||||||
|
|
||||||
|
// Allow ptrace() of any process
|
||||||
|
CAP_SYS_PTRACE = Cap(19)
|
||||||
|
|
||||||
|
// Allow configuration of process accounting
|
||||||
|
CAP_SYS_PACCT = Cap(20)
|
||||||
|
|
||||||
|
// Allow configuration of the secure attention key
|
||||||
|
// Allow administration of the random device
|
||||||
|
// Allow examination and configuration of disk quotas
|
||||||
|
// Allow setting the domainname
|
||||||
|
// Allow setting the hostname
|
||||||
|
// Allow calling bdflush()
|
||||||
|
// Allow mount() and umount(), setting up new smb connection
|
||||||
|
// Allow some autofs root ioctls
|
||||||
|
// Allow nfsservctl
|
||||||
|
// Allow VM86_REQUEST_IRQ
|
||||||
|
// Allow to read/write pci config on alpha
|
||||||
|
// Allow irix_prctl on mips (setstacksize)
|
||||||
|
// Allow flushing all cache on m68k (sys_cacheflush)
|
||||||
|
// Allow removing semaphores
|
||||||
|
// Used instead of CAP_CHOWN to "chown" IPC message queues, semaphores
|
||||||
|
// and shared memory
|
||||||
|
// Allow locking/unlocking of shared memory segment
|
||||||
|
// Allow turning swap on/off
|
||||||
|
// Allow forged pids on socket credentials passing
|
||||||
|
// Allow setting readahead and flushing buffers on block devices
|
||||||
|
// Allow setting geometry in floppy driver
|
||||||
|
// Allow turning DMA on/off in xd driver
|
||||||
|
// Allow administration of md devices (mostly the above, but some
|
||||||
|
// extra ioctls)
|
||||||
|
// Allow tuning the ide driver
|
||||||
|
// Allow access to the nvram device
|
||||||
|
// Allow administration of apm_bios, serial and bttv (TV) device
|
||||||
|
// Allow manufacturer commands in isdn CAPI support driver
|
||||||
|
// Allow reading non-standardized portions of pci configuration space
|
||||||
|
// Allow DDI debug ioctl on sbpcd driver
|
||||||
|
// Allow setting up serial ports
|
||||||
|
// Allow sending raw qic-117 commands
|
||||||
|
// Allow enabling/disabling tagged queuing on SCSI controllers and sending
|
||||||
|
// arbitrary SCSI commands
|
||||||
|
// Allow setting encryption key on loopback filesystem
|
||||||
|
// Allow setting zone reclaim policy
|
||||||
|
// Allow everything under CAP_BPF and CAP_PERFMON for backward compatibility
|
||||||
|
CAP_SYS_ADMIN = Cap(21)
|
||||||
|
|
||||||
|
// Allow use of reboot()
|
||||||
|
CAP_SYS_BOOT = Cap(22)
|
||||||
|
|
||||||
|
// Allow raising priority and setting priority on other (different
|
||||||
|
// UID) processes
|
||||||
|
// Allow use of FIFO and round-robin (realtime) scheduling on own
|
||||||
|
// processes and setting the scheduling algorithm used by another
|
||||||
|
// process.
|
||||||
|
// Allow setting cpu affinity on other processes
|
||||||
|
CAP_SYS_NICE = Cap(23)
|
||||||
|
|
||||||
|
// Override resource limits. Set resource limits.
|
||||||
|
// Override quota limits.
|
||||||
|
// Override reserved space on ext2 filesystem
|
||||||
|
// Modify data journaling mode on ext3 filesystem (uses journaling
|
||||||
|
// resources)
|
||||||
|
// NOTE: ext2 honors fsuid when checking for resource overrides, so
|
||||||
|
// you can override using fsuid too
|
||||||
|
// Override size restrictions on IPC message queues
|
||||||
|
// Allow more than 64hz interrupts from the real-time clock
|
||||||
|
// Override max number of consoles on console allocation
|
||||||
|
// Override max number of keymaps
|
||||||
|
// Control memory reclaim behavior
|
||||||
|
CAP_SYS_RESOURCE = Cap(24)
|
||||||
|
|
||||||
|
// Allow manipulation of system clock
|
||||||
|
// Allow irix_stime on mips
|
||||||
|
// Allow setting the real-time clock
|
||||||
|
CAP_SYS_TIME = Cap(25)
|
||||||
|
|
||||||
|
// Allow configuration of tty devices
|
||||||
|
// Allow vhangup() of tty
|
||||||
|
CAP_SYS_TTY_CONFIG = Cap(26)
|
||||||
|
|
||||||
|
// Allow the privileged aspects of mknod()
|
||||||
|
CAP_MKNOD = Cap(27)
|
||||||
|
|
||||||
|
// Allow taking of leases on files
|
||||||
|
CAP_LEASE = Cap(28)
|
||||||
|
|
||||||
|
CAP_AUDIT_WRITE = Cap(29)
|
||||||
|
CAP_AUDIT_CONTROL = Cap(30)
|
||||||
|
CAP_SETFCAP = Cap(31)
|
||||||
|
|
||||||
|
// Override MAC access.
|
||||||
|
// The base kernel enforces no MAC policy.
|
||||||
|
// An LSM may enforce a MAC policy, and if it does and it chooses
|
||||||
|
// to implement capability based overrides of that policy, this is
|
||||||
|
// the capability it should use to do so.
|
||||||
|
CAP_MAC_OVERRIDE = Cap(32)
|
||||||
|
|
||||||
|
// Allow MAC configuration or state changes.
|
||||||
|
// The base kernel requires no MAC configuration.
|
||||||
|
// An LSM may enforce a MAC policy, and if it does and it chooses
|
||||||
|
// to implement capability based checks on modifications to that
|
||||||
|
// policy or the data required to maintain it, this is the
|
||||||
|
// capability it should use to do so.
|
||||||
|
CAP_MAC_ADMIN = Cap(33)
|
||||||
|
|
||||||
|
// Allow configuring the kernel's syslog (printk behaviour)
|
||||||
|
CAP_SYSLOG = Cap(34)
|
||||||
|
|
||||||
|
// Allow triggering something that will wake the system
|
||||||
|
CAP_WAKE_ALARM = Cap(35)
|
||||||
|
|
||||||
|
// Allow preventing system suspends
|
||||||
|
CAP_BLOCK_SUSPEND = Cap(36)
|
||||||
|
|
||||||
|
// Allow reading the audit log via multicast netlink socket
|
||||||
|
CAP_AUDIT_READ = Cap(37)
|
||||||
|
|
||||||
|
// Allow system performance and observability privileged operations
|
||||||
|
// using perf_events, i915_perf and other kernel subsystems
|
||||||
|
CAP_PERFMON = Cap(38)
|
||||||
|
|
||||||
|
// CAP_BPF allows the following BPF operations:
|
||||||
|
// - Creating all types of BPF maps
|
||||||
|
// - Advanced verifier features
|
||||||
|
// - Indirect variable access
|
||||||
|
// - Bounded loops
|
||||||
|
// - BPF to BPF function calls
|
||||||
|
// - Scalar precision tracking
|
||||||
|
// - Larger complexity limits
|
||||||
|
// - Dead code elimination
|
||||||
|
// - And potentially other features
|
||||||
|
// - Loading BPF Type Format (BTF) data
|
||||||
|
// - Retrieve xlated and JITed code of BPF programs
|
||||||
|
// - Use bpf_spin_lock() helper
|
||||||
|
//
|
||||||
|
// CAP_PERFMON relaxes the verifier checks further:
|
||||||
|
// - BPF progs can use of pointer-to-integer conversions
|
||||||
|
// - speculation attack hardening measures are bypassed
|
||||||
|
// - bpf_probe_read to read arbitrary kernel memory is allowed
|
||||||
|
// - bpf_trace_printk to print kernel memory is allowed
|
||||||
|
//
|
||||||
|
// CAP_SYS_ADMIN is required to use bpf_probe_write_user.
|
||||||
|
//
|
||||||
|
// CAP_SYS_ADMIN is required to iterate system wide loaded
|
||||||
|
// programs, maps, links, BTFs and convert their IDs to file descriptors.
|
||||||
|
//
|
||||||
|
// CAP_PERFMON and CAP_BPF are required to load tracing programs.
|
||||||
|
// CAP_NET_ADMIN and CAP_BPF are required to load networking programs.
|
||||||
|
CAP_BPF = Cap(39)
|
||||||
|
|
||||||
|
// Allow checkpoint/restore related operations.
|
||||||
|
// Introduced in kernel 5.9
|
||||||
|
CAP_CHECKPOINT_RESTORE = Cap(40)
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Highest valid capability of the running kernel.
|
||||||
|
CAP_LAST_CAP = Cap(63)
|
||||||
|
|
||||||
|
capUpperMask = ^uint32(0)
|
||||||
|
)
|
138
src/runtime/vendor/github.com/syndtr/gocapability/capability/enum_gen.go
generated
vendored
Normal file
138
src/runtime/vendor/github.com/syndtr/gocapability/capability/enum_gen.go
generated
vendored
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
// generated file; DO NOT EDIT - use go generate in directory with source
|
||||||
|
|
||||||
|
package capability
|
||||||
|
|
||||||
|
func (c Cap) String() string {
|
||||||
|
switch c {
|
||||||
|
case CAP_CHOWN:
|
||||||
|
return "chown"
|
||||||
|
case CAP_DAC_OVERRIDE:
|
||||||
|
return "dac_override"
|
||||||
|
case CAP_DAC_READ_SEARCH:
|
||||||
|
return "dac_read_search"
|
||||||
|
case CAP_FOWNER:
|
||||||
|
return "fowner"
|
||||||
|
case CAP_FSETID:
|
||||||
|
return "fsetid"
|
||||||
|
case CAP_KILL:
|
||||||
|
return "kill"
|
||||||
|
case CAP_SETGID:
|
||||||
|
return "setgid"
|
||||||
|
case CAP_SETUID:
|
||||||
|
return "setuid"
|
||||||
|
case CAP_SETPCAP:
|
||||||
|
return "setpcap"
|
||||||
|
case CAP_LINUX_IMMUTABLE:
|
||||||
|
return "linux_immutable"
|
||||||
|
case CAP_NET_BIND_SERVICE:
|
||||||
|
return "net_bind_service"
|
||||||
|
case CAP_NET_BROADCAST:
|
||||||
|
return "net_broadcast"
|
||||||
|
case CAP_NET_ADMIN:
|
||||||
|
return "net_admin"
|
||||||
|
case CAP_NET_RAW:
|
||||||
|
return "net_raw"
|
||||||
|
case CAP_IPC_LOCK:
|
||||||
|
return "ipc_lock"
|
||||||
|
case CAP_IPC_OWNER:
|
||||||
|
return "ipc_owner"
|
||||||
|
case CAP_SYS_MODULE:
|
||||||
|
return "sys_module"
|
||||||
|
case CAP_SYS_RAWIO:
|
||||||
|
return "sys_rawio"
|
||||||
|
case CAP_SYS_CHROOT:
|
||||||
|
return "sys_chroot"
|
||||||
|
case CAP_SYS_PTRACE:
|
||||||
|
return "sys_ptrace"
|
||||||
|
case CAP_SYS_PACCT:
|
||||||
|
return "sys_pacct"
|
||||||
|
case CAP_SYS_ADMIN:
|
||||||
|
return "sys_admin"
|
||||||
|
case CAP_SYS_BOOT:
|
||||||
|
return "sys_boot"
|
||||||
|
case CAP_SYS_NICE:
|
||||||
|
return "sys_nice"
|
||||||
|
case CAP_SYS_RESOURCE:
|
||||||
|
return "sys_resource"
|
||||||
|
case CAP_SYS_TIME:
|
||||||
|
return "sys_time"
|
||||||
|
case CAP_SYS_TTY_CONFIG:
|
||||||
|
return "sys_tty_config"
|
||||||
|
case CAP_MKNOD:
|
||||||
|
return "mknod"
|
||||||
|
case CAP_LEASE:
|
||||||
|
return "lease"
|
||||||
|
case CAP_AUDIT_WRITE:
|
||||||
|
return "audit_write"
|
||||||
|
case CAP_AUDIT_CONTROL:
|
||||||
|
return "audit_control"
|
||||||
|
case CAP_SETFCAP:
|
||||||
|
return "setfcap"
|
||||||
|
case CAP_MAC_OVERRIDE:
|
||||||
|
return "mac_override"
|
||||||
|
case CAP_MAC_ADMIN:
|
||||||
|
return "mac_admin"
|
||||||
|
case CAP_SYSLOG:
|
||||||
|
return "syslog"
|
||||||
|
case CAP_WAKE_ALARM:
|
||||||
|
return "wake_alarm"
|
||||||
|
case CAP_BLOCK_SUSPEND:
|
||||||
|
return "block_suspend"
|
||||||
|
case CAP_AUDIT_READ:
|
||||||
|
return "audit_read"
|
||||||
|
case CAP_PERFMON:
|
||||||
|
return "perfmon"
|
||||||
|
case CAP_BPF:
|
||||||
|
return "bpf"
|
||||||
|
case CAP_CHECKPOINT_RESTORE:
|
||||||
|
return "checkpoint_restore"
|
||||||
|
}
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns list of all supported capabilities
|
||||||
|
func List() []Cap {
|
||||||
|
return []Cap{
|
||||||
|
CAP_CHOWN,
|
||||||
|
CAP_DAC_OVERRIDE,
|
||||||
|
CAP_DAC_READ_SEARCH,
|
||||||
|
CAP_FOWNER,
|
||||||
|
CAP_FSETID,
|
||||||
|
CAP_KILL,
|
||||||
|
CAP_SETGID,
|
||||||
|
CAP_SETUID,
|
||||||
|
CAP_SETPCAP,
|
||||||
|
CAP_LINUX_IMMUTABLE,
|
||||||
|
CAP_NET_BIND_SERVICE,
|
||||||
|
CAP_NET_BROADCAST,
|
||||||
|
CAP_NET_ADMIN,
|
||||||
|
CAP_NET_RAW,
|
||||||
|
CAP_IPC_LOCK,
|
||||||
|
CAP_IPC_OWNER,
|
||||||
|
CAP_SYS_MODULE,
|
||||||
|
CAP_SYS_RAWIO,
|
||||||
|
CAP_SYS_CHROOT,
|
||||||
|
CAP_SYS_PTRACE,
|
||||||
|
CAP_SYS_PACCT,
|
||||||
|
CAP_SYS_ADMIN,
|
||||||
|
CAP_SYS_BOOT,
|
||||||
|
CAP_SYS_NICE,
|
||||||
|
CAP_SYS_RESOURCE,
|
||||||
|
CAP_SYS_TIME,
|
||||||
|
CAP_SYS_TTY_CONFIG,
|
||||||
|
CAP_MKNOD,
|
||||||
|
CAP_LEASE,
|
||||||
|
CAP_AUDIT_WRITE,
|
||||||
|
CAP_AUDIT_CONTROL,
|
||||||
|
CAP_SETFCAP,
|
||||||
|
CAP_MAC_OVERRIDE,
|
||||||
|
CAP_MAC_ADMIN,
|
||||||
|
CAP_SYSLOG,
|
||||||
|
CAP_WAKE_ALARM,
|
||||||
|
CAP_BLOCK_SUSPEND,
|
||||||
|
CAP_AUDIT_READ,
|
||||||
|
CAP_PERFMON,
|
||||||
|
CAP_BPF,
|
||||||
|
CAP_CHECKPOINT_RESTORE,
|
||||||
|
}
|
||||||
|
}
|
154
src/runtime/vendor/github.com/syndtr/gocapability/capability/syscall_linux.go
generated
vendored
Normal file
154
src/runtime/vendor/github.com/syndtr/gocapability/capability/syscall_linux.go
generated
vendored
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
package capability
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type capHeader struct {
|
||||||
|
version uint32
|
||||||
|
pid int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type capData struct {
|
||||||
|
effective uint32
|
||||||
|
permitted uint32
|
||||||
|
inheritable uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func capget(hdr *capHeader, data *capData) (err error) {
|
||||||
|
_, _, e1 := syscall.Syscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func capset(hdr *capHeader, data *capData) (err error) {
|
||||||
|
_, _, e1 := syscall.Syscall(syscall.SYS_CAPSET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// not yet in syscall
|
||||||
|
const (
|
||||||
|
pr_CAP_AMBIENT = 47
|
||||||
|
pr_CAP_AMBIENT_IS_SET = uintptr(1)
|
||||||
|
pr_CAP_AMBIENT_RAISE = uintptr(2)
|
||||||
|
pr_CAP_AMBIENT_LOWER = uintptr(3)
|
||||||
|
pr_CAP_AMBIENT_CLEAR_ALL = uintptr(4)
|
||||||
|
)
|
||||||
|
|
||||||
|
func prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) {
|
||||||
|
_, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
vfsXattrName = "security.capability"
|
||||||
|
|
||||||
|
vfsCapVerMask = 0xff000000
|
||||||
|
vfsCapVer1 = 0x01000000
|
||||||
|
vfsCapVer2 = 0x02000000
|
||||||
|
|
||||||
|
vfsCapFlagMask = ^vfsCapVerMask
|
||||||
|
vfsCapFlageffective = 0x000001
|
||||||
|
|
||||||
|
vfscapDataSizeV1 = 4 * (1 + 2*1)
|
||||||
|
vfscapDataSizeV2 = 4 * (1 + 2*2)
|
||||||
|
)
|
||||||
|
|
||||||
|
type vfscapData struct {
|
||||||
|
magic uint32
|
||||||
|
data [2]struct {
|
||||||
|
permitted uint32
|
||||||
|
inheritable uint32
|
||||||
|
}
|
||||||
|
effective [2]uint32
|
||||||
|
version int8
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
_vfsXattrName *byte
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
_vfsXattrName, _ = syscall.BytePtrFromString(vfsXattrName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getVfsCap(path string, dest *vfscapData) (err error) {
|
||||||
|
var _p0 *byte
|
||||||
|
_p0, err = syscall.BytePtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r0, _, e1 := syscall.Syscall6(syscall.SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(dest)), vfscapDataSizeV2, 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
if e1 == syscall.ENODATA {
|
||||||
|
dest.version = 2
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
switch dest.magic & vfsCapVerMask {
|
||||||
|
case vfsCapVer1:
|
||||||
|
dest.version = 1
|
||||||
|
if r0 != vfscapDataSizeV1 {
|
||||||
|
return syscall.EINVAL
|
||||||
|
}
|
||||||
|
dest.data[1].permitted = 0
|
||||||
|
dest.data[1].inheritable = 0
|
||||||
|
case vfsCapVer2:
|
||||||
|
dest.version = 2
|
||||||
|
if r0 != vfscapDataSizeV2 {
|
||||||
|
return syscall.EINVAL
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return syscall.EINVAL
|
||||||
|
}
|
||||||
|
if dest.magic&vfsCapFlageffective != 0 {
|
||||||
|
dest.effective[0] = dest.data[0].permitted | dest.data[0].inheritable
|
||||||
|
dest.effective[1] = dest.data[1].permitted | dest.data[1].inheritable
|
||||||
|
} else {
|
||||||
|
dest.effective[0] = 0
|
||||||
|
dest.effective[1] = 0
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func setVfsCap(path string, data *vfscapData) (err error) {
|
||||||
|
var _p0 *byte
|
||||||
|
_p0, err = syscall.BytePtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var size uintptr
|
||||||
|
if data.version == 1 {
|
||||||
|
data.magic = vfsCapVer1
|
||||||
|
size = vfscapDataSizeV1
|
||||||
|
} else if data.version == 2 {
|
||||||
|
data.magic = vfsCapVer2
|
||||||
|
if data.effective[0] != 0 || data.effective[1] != 0 {
|
||||||
|
data.magic |= vfsCapFlageffective
|
||||||
|
}
|
||||||
|
size = vfscapDataSizeV2
|
||||||
|
} else {
|
||||||
|
return syscall.EINVAL
|
||||||
|
}
|
||||||
|
_, _, e1 := syscall.Syscall6(syscall.SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(data)), size, 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
27
src/runtime/vendor/golang.org/x/mod/LICENSE
generated
vendored
Normal file
27
src/runtime/vendor/golang.org/x/mod/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
src/runtime/vendor/golang.org/x/mod/PATENTS
generated
vendored
Normal file
22
src/runtime/vendor/golang.org/x/mod/PATENTS
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Additional IP Rights Grant (Patents)
|
||||||
|
|
||||||
|
"This implementation" means the copyrightable works distributed by
|
||||||
|
Google as part of the Go project.
|
||||||
|
|
||||||
|
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||||
|
patent license to make, have made, use, offer to sell, sell, import,
|
||||||
|
transfer and otherwise run, modify and propagate the contents of this
|
||||||
|
implementation of Go, where such license applies only to those patent
|
||||||
|
claims, both currently owned or controlled by Google and acquired in
|
||||||
|
the future, licensable by Google that are necessarily infringed by this
|
||||||
|
implementation of Go. This grant does not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of this
|
||||||
|
implementation. If you or your agent or exclusive licensee institute or
|
||||||
|
order or agree to the institution of patent litigation against any
|
||||||
|
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that this implementation of Go or any code incorporated within this
|
||||||
|
implementation of Go constitutes direct or contributory patent
|
||||||
|
infringement, or inducement of patent infringement, then any patent
|
||||||
|
rights granted to you under this License for this implementation of Go
|
||||||
|
shall terminate as of the date such litigation is filed.
|
401
src/runtime/vendor/golang.org/x/mod/semver/semver.go
generated
vendored
Normal file
401
src/runtime/vendor/golang.org/x/mod/semver/semver.go
generated
vendored
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package semver implements comparison of semantic version strings.
|
||||||
|
// In this package, semantic version strings must begin with a leading "v",
|
||||||
|
// as in "v1.0.0".
|
||||||
|
//
|
||||||
|
// The general form of a semantic version string accepted by this package is
|
||||||
|
//
|
||||||
|
// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]]
|
||||||
|
//
|
||||||
|
// where square brackets indicate optional parts of the syntax;
|
||||||
|
// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros;
|
||||||
|
// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers
|
||||||
|
// using only alphanumeric characters and hyphens; and
|
||||||
|
// all-numeric PRERELEASE identifiers must not have leading zeros.
|
||||||
|
//
|
||||||
|
// This package follows Semantic Versioning 2.0.0 (see semver.org)
|
||||||
|
// with two exceptions. First, it requires the "v" prefix. Second, it recognizes
|
||||||
|
// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes)
|
||||||
|
// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
|
||||||
|
package semver
|
||||||
|
|
||||||
|
import "sort"
|
||||||
|
|
||||||
|
// parsed returns the parsed form of a semantic version string.
|
||||||
|
type parsed struct {
|
||||||
|
major string
|
||||||
|
minor string
|
||||||
|
patch string
|
||||||
|
short string
|
||||||
|
prerelease string
|
||||||
|
build string
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsValid reports whether v is a valid semantic version string.
|
||||||
|
func IsValid(v string) bool {
|
||||||
|
_, ok := parse(v)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// Canonical returns the canonical formatting of the semantic version v.
|
||||||
|
// It fills in any missing .MINOR or .PATCH and discards build metadata.
|
||||||
|
// Two semantic versions compare equal only if their canonical formattings
|
||||||
|
// are identical strings.
|
||||||
|
// The canonical invalid semantic version is the empty string.
|
||||||
|
func Canonical(v string) string {
|
||||||
|
p, ok := parse(v)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if p.build != "" {
|
||||||
|
return v[:len(v)-len(p.build)]
|
||||||
|
}
|
||||||
|
if p.short != "" {
|
||||||
|
return v + p.short
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Major returns the major version prefix of the semantic version v.
|
||||||
|
// For example, Major("v2.1.0") == "v2".
|
||||||
|
// If v is an invalid semantic version string, Major returns the empty string.
|
||||||
|
func Major(v string) string {
|
||||||
|
pv, ok := parse(v)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return v[:1+len(pv.major)]
|
||||||
|
}
|
||||||
|
|
||||||
|
// MajorMinor returns the major.minor version prefix of the semantic version v.
|
||||||
|
// For example, MajorMinor("v2.1.0") == "v2.1".
|
||||||
|
// If v is an invalid semantic version string, MajorMinor returns the empty string.
|
||||||
|
func MajorMinor(v string) string {
|
||||||
|
pv, ok := parse(v)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
i := 1 + len(pv.major)
|
||||||
|
if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor {
|
||||||
|
return v[:j]
|
||||||
|
}
|
||||||
|
return v[:i] + "." + pv.minor
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prerelease returns the prerelease suffix of the semantic version v.
|
||||||
|
// For example, Prerelease("v2.1.0-pre+meta") == "-pre".
|
||||||
|
// If v is an invalid semantic version string, Prerelease returns the empty string.
|
||||||
|
func Prerelease(v string) string {
|
||||||
|
pv, ok := parse(v)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return pv.prerelease
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build returns the build suffix of the semantic version v.
|
||||||
|
// For example, Build("v2.1.0+meta") == "+meta".
|
||||||
|
// If v is an invalid semantic version string, Build returns the empty string.
|
||||||
|
func Build(v string) string {
|
||||||
|
pv, ok := parse(v)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return pv.build
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare returns an integer comparing two versions according to
|
||||||
|
// semantic version precedence.
|
||||||
|
// The result will be 0 if v == w, -1 if v < w, or +1 if v > w.
|
||||||
|
//
|
||||||
|
// An invalid semantic version string is considered less than a valid one.
|
||||||
|
// All invalid semantic version strings compare equal to each other.
|
||||||
|
func Compare(v, w string) int {
|
||||||
|
pv, ok1 := parse(v)
|
||||||
|
pw, ok2 := parse(w)
|
||||||
|
if !ok1 && !ok2 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if !ok1 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if !ok2 {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
if c := compareInt(pv.major, pw.major); c != 0 {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
if c := compareInt(pv.minor, pw.minor); c != 0 {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
if c := compareInt(pv.patch, pw.patch); c != 0 {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return comparePrerelease(pv.prerelease, pw.prerelease)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Max canonicalizes its arguments and then returns the version string
|
||||||
|
// that compares greater.
|
||||||
|
//
|
||||||
|
// Deprecated: use Compare instead. In most cases, returning a canonicalized
|
||||||
|
// version is not expected or desired.
|
||||||
|
func Max(v, w string) string {
|
||||||
|
v = Canonical(v)
|
||||||
|
w = Canonical(w)
|
||||||
|
if Compare(v, w) > 0 {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByVersion implements sort.Interface for sorting semantic version strings.
|
||||||
|
type ByVersion []string
|
||||||
|
|
||||||
|
func (vs ByVersion) Len() int { return len(vs) }
|
||||||
|
func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] }
|
||||||
|
func (vs ByVersion) Less(i, j int) bool {
|
||||||
|
cmp := Compare(vs[i], vs[j])
|
||||||
|
if cmp != 0 {
|
||||||
|
return cmp < 0
|
||||||
|
}
|
||||||
|
return vs[i] < vs[j]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort sorts a list of semantic version strings using ByVersion.
|
||||||
|
func Sort(list []string) {
|
||||||
|
sort.Sort(ByVersion(list))
|
||||||
|
}
|
||||||
|
|
||||||
|
func parse(v string) (p parsed, ok bool) {
|
||||||
|
if v == "" || v[0] != 'v' {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.major, v, ok = parseInt(v[1:])
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v == "" {
|
||||||
|
p.minor = "0"
|
||||||
|
p.patch = "0"
|
||||||
|
p.short = ".0.0"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v[0] != '.' {
|
||||||
|
ok = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.minor, v, ok = parseInt(v[1:])
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v == "" {
|
||||||
|
p.patch = "0"
|
||||||
|
p.short = ".0"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v[0] != '.' {
|
||||||
|
ok = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.patch, v, ok = parseInt(v[1:])
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(v) > 0 && v[0] == '-' {
|
||||||
|
p.prerelease, v, ok = parsePrerelease(v)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(v) > 0 && v[0] == '+' {
|
||||||
|
p.build, v, ok = parseBuild(v)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v != "" {
|
||||||
|
ok = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ok = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseInt(v string) (t, rest string, ok bool) {
|
||||||
|
if v == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v[0] < '0' || '9' < v[0] {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i := 1
|
||||||
|
for i < len(v) && '0' <= v[i] && v[i] <= '9' {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if v[0] == '0' && i != 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return v[:i], v[i:], true
|
||||||
|
}
|
||||||
|
|
||||||
|
func parsePrerelease(v string) (t, rest string, ok bool) {
|
||||||
|
// "A pre-release version MAY be denoted by appending a hyphen and
|
||||||
|
// a series of dot separated identifiers immediately following the patch version.
|
||||||
|
// Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].
|
||||||
|
// Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes."
|
||||||
|
if v == "" || v[0] != '-' {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i := 1
|
||||||
|
start := 1
|
||||||
|
for i < len(v) && v[i] != '+' {
|
||||||
|
if !isIdentChar(v[i]) && v[i] != '.' {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v[i] == '.' {
|
||||||
|
if start == i || isBadNum(v[start:i]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
start = i + 1
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if start == i || isBadNum(v[start:i]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return v[:i], v[i:], true
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseBuild(v string) (t, rest string, ok bool) {
|
||||||
|
if v == "" || v[0] != '+' {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
i := 1
|
||||||
|
start := 1
|
||||||
|
for i < len(v) {
|
||||||
|
if !isIdentChar(v[i]) && v[i] != '.' {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v[i] == '.' {
|
||||||
|
if start == i {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
start = i + 1
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if start == i {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return v[:i], v[i:], true
|
||||||
|
}
|
||||||
|
|
||||||
|
func isIdentChar(c byte) bool {
|
||||||
|
return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
func isBadNum(v string) bool {
|
||||||
|
i := 0
|
||||||
|
for i < len(v) && '0' <= v[i] && v[i] <= '9' {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return i == len(v) && i > 1 && v[0] == '0'
|
||||||
|
}
|
||||||
|
|
||||||
|
func isNum(v string) bool {
|
||||||
|
i := 0
|
||||||
|
for i < len(v) && '0' <= v[i] && v[i] <= '9' {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return i == len(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func compareInt(x, y string) int {
|
||||||
|
if x == y {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if len(x) < len(y) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if len(x) > len(y) {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
if x < y {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func comparePrerelease(x, y string) int {
|
||||||
|
// "When major, minor, and patch are equal, a pre-release version has
|
||||||
|
// lower precedence than a normal version.
|
||||||
|
// Example: 1.0.0-alpha < 1.0.0.
|
||||||
|
// Precedence for two pre-release versions with the same major, minor,
|
||||||
|
// and patch version MUST be determined by comparing each dot separated
|
||||||
|
// identifier from left to right until a difference is found as follows:
|
||||||
|
// identifiers consisting of only digits are compared numerically and
|
||||||
|
// identifiers with letters or hyphens are compared lexically in ASCII
|
||||||
|
// sort order. Numeric identifiers always have lower precedence than
|
||||||
|
// non-numeric identifiers. A larger set of pre-release fields has a
|
||||||
|
// higher precedence than a smaller set, if all of the preceding
|
||||||
|
// identifiers are equal.
|
||||||
|
// Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta <
|
||||||
|
// 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0."
|
||||||
|
if x == y {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if x == "" {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
if y == "" {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
for x != "" && y != "" {
|
||||||
|
x = x[1:] // skip - or .
|
||||||
|
y = y[1:] // skip - or .
|
||||||
|
var dx, dy string
|
||||||
|
dx, x = nextIdent(x)
|
||||||
|
dy, y = nextIdent(y)
|
||||||
|
if dx != dy {
|
||||||
|
ix := isNum(dx)
|
||||||
|
iy := isNum(dy)
|
||||||
|
if ix != iy {
|
||||||
|
if ix {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ix {
|
||||||
|
if len(dx) < len(dy) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if len(dx) > len(dy) {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if dx < dy {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if x == "" {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func nextIdent(x string) (dx, rest string) {
|
||||||
|
i := 0
|
||||||
|
for i < len(x) && x[i] != '.' {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return x[:i], x[i:]
|
||||||
|
}
|
31
src/runtime/vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s
generated
vendored
Normal file
31
src/runtime/vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2022 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build (darwin || freebsd || netbsd || openbsd) && gc
|
||||||
|
// +build darwin freebsd netbsd openbsd
|
||||||
|
// +build gc
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for ppc64, BSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
4
src/runtime/vendor/golang.org/x/sys/unix/dirent.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/dirent.go
generated
vendored
@ -2,8 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
20
src/runtime/vendor/golang.org/x/sys/unix/ioctl_linux.go
generated
vendored
20
src/runtime/vendor/golang.org/x/sys/unix/ioctl_linux.go
generated
vendored
@ -4,9 +4,7 @@
|
|||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
import (
|
import "unsafe"
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IoctlRetInt performs an ioctl operation specified by req on a device
|
// IoctlRetInt performs an ioctl operation specified by req on a device
|
||||||
// associated with opened file descriptor fd, and returns a non-negative
|
// associated with opened file descriptor fd, and returns a non-negative
|
||||||
@ -217,3 +215,19 @@ func IoctlKCMAttach(fd int, info KCMAttach) error {
|
|||||||
func IoctlKCMUnattach(fd int, info KCMUnattach) error {
|
func IoctlKCMUnattach(fd int, info KCMUnattach) error {
|
||||||
return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))
|
return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IoctlLoopGetStatus64 gets the status of the loop device associated with the
|
||||||
|
// file descriptor fd using the LOOP_GET_STATUS64 operation.
|
||||||
|
func IoctlLoopGetStatus64(fd int) (*LoopInfo64, error) {
|
||||||
|
var value LoopInfo64
|
||||||
|
if err := ioctlPtr(fd, LOOP_GET_STATUS64, unsafe.Pointer(&value)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IoctlLoopSetStatus64 sets the status of the loop device associated with the
|
||||||
|
// file descriptor fd using the LOOP_SET_STATUS64 operation.
|
||||||
|
func IoctlLoopSetStatus64(fd int, value *LoopInfo64) error {
|
||||||
|
return ioctlPtr(fd, LOOP_SET_STATUS64, unsafe.Pointer(value))
|
||||||
|
}
|
||||||
|
45
src/runtime/vendor/golang.org/x/sys/unix/mkall.sh
generated
vendored
45
src/runtime/vendor/golang.org/x/sys/unix/mkall.sh
generated
vendored
@ -73,12 +73,12 @@ aix_ppc64)
|
|||||||
darwin_amd64)
|
darwin_amd64)
|
||||||
mkerrors="$mkerrors -m64"
|
mkerrors="$mkerrors -m64"
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||||
mkasm="go run mkasm_darwin.go"
|
mkasm="go run mkasm.go"
|
||||||
;;
|
;;
|
||||||
darwin_arm64)
|
darwin_arm64)
|
||||||
mkerrors="$mkerrors -m64"
|
mkerrors="$mkerrors -m64"
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||||
mkasm="go run mkasm_darwin.go"
|
mkasm="go run mkasm.go"
|
||||||
;;
|
;;
|
||||||
dragonfly_amd64)
|
dragonfly_amd64)
|
||||||
mkerrors="$mkerrors -m64"
|
mkerrors="$mkerrors -m64"
|
||||||
@ -142,33 +142,33 @@ netbsd_arm64)
|
|||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||||
;;
|
;;
|
||||||
openbsd_386)
|
openbsd_386)
|
||||||
|
mkasm="go run mkasm.go"
|
||||||
mkerrors="$mkerrors -m32"
|
mkerrors="$mkerrors -m32"
|
||||||
mksyscall="go run mksyscall.go -l32 -openbsd"
|
mksyscall="go run mksyscall.go -l32 -openbsd -libc"
|
||||||
mksysctl="go run mksysctl_openbsd.go"
|
mksysctl="go run mksysctl_openbsd.go"
|
||||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||||
;;
|
;;
|
||||||
openbsd_amd64)
|
openbsd_amd64)
|
||||||
|
mkasm="go run mkasm.go"
|
||||||
mkerrors="$mkerrors -m64"
|
mkerrors="$mkerrors -m64"
|
||||||
mksyscall="go run mksyscall.go -openbsd"
|
mksyscall="go run mksyscall.go -openbsd -libc"
|
||||||
mksysctl="go run mksysctl_openbsd.go"
|
mksysctl="go run mksysctl_openbsd.go"
|
||||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||||
;;
|
;;
|
||||||
openbsd_arm)
|
openbsd_arm)
|
||||||
|
mkasm="go run mkasm.go"
|
||||||
mkerrors="$mkerrors"
|
mkerrors="$mkerrors"
|
||||||
mksyscall="go run mksyscall.go -l32 -openbsd -arm"
|
mksyscall="go run mksyscall.go -l32 -openbsd -arm -libc"
|
||||||
mksysctl="go run mksysctl_openbsd.go"
|
mksysctl="go run mksysctl_openbsd.go"
|
||||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
# Let the type of C char be signed for making the bare syscall
|
# Let the type of C char be signed for making the bare syscall
|
||||||
# API consistent across platforms.
|
# API consistent across platforms.
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||||
;;
|
;;
|
||||||
openbsd_arm64)
|
openbsd_arm64)
|
||||||
|
mkasm="go run mkasm.go"
|
||||||
mkerrors="$mkerrors -m64"
|
mkerrors="$mkerrors -m64"
|
||||||
mksyscall="go run mksyscall.go -openbsd"
|
mksyscall="go run mksyscall.go -openbsd -libc"
|
||||||
mksysctl="go run mksysctl_openbsd.go"
|
mksysctl="go run mksysctl_openbsd.go"
|
||||||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
|
|
||||||
# Let the type of C char be signed for making the bare syscall
|
# Let the type of C char be signed for making the bare syscall
|
||||||
# API consistent across platforms.
|
# API consistent across platforms.
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||||
@ -182,6 +182,24 @@ openbsd_mips64)
|
|||||||
# API consistent across platforms.
|
# API consistent across platforms.
|
||||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||||
;;
|
;;
|
||||||
|
openbsd_ppc64)
|
||||||
|
mkasm="go run mkasm.go"
|
||||||
|
mkerrors="$mkerrors -m64"
|
||||||
|
mksyscall="go run mksyscall.go -openbsd -libc"
|
||||||
|
mksysctl="go run mksysctl_openbsd.go"
|
||||||
|
# Let the type of C char be signed for making the bare syscall
|
||||||
|
# API consistent across platforms.
|
||||||
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||||
|
;;
|
||||||
|
openbsd_riscv64)
|
||||||
|
mkasm="go run mkasm.go"
|
||||||
|
mkerrors="$mkerrors -m64"
|
||||||
|
mksyscall="go run mksyscall.go -openbsd -libc"
|
||||||
|
mksysctl="go run mksysctl_openbsd.go"
|
||||||
|
# Let the type of C char be signed for making the bare syscall
|
||||||
|
# API consistent across platforms.
|
||||||
|
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||||
|
;;
|
||||||
solaris_amd64)
|
solaris_amd64)
|
||||||
mksyscall="go run mksyscall_solaris.go"
|
mksyscall="go run mksyscall_solaris.go"
|
||||||
mkerrors="$mkerrors -m64"
|
mkerrors="$mkerrors -m64"
|
||||||
@ -214,11 +232,6 @@ esac
|
|||||||
if [ "$GOOSARCH" == "aix_ppc64" ]; then
|
if [ "$GOOSARCH" == "aix_ppc64" ]; then
|
||||||
# aix/ppc64 script generates files instead of writing to stdin.
|
# aix/ppc64 script generates files instead of writing to stdin.
|
||||||
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
|
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
|
||||||
elif [ "$GOOS" == "darwin" ]; then
|
|
||||||
# 1.12 and later, syscalls via libSystem
|
|
||||||
echo "$mksyscall -tags $GOOS,$GOARCH,go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
|
|
||||||
# 1.13 and later, syscalls via libSystem (including syscallPtr)
|
|
||||||
echo "$mksyscall -tags $GOOS,$GOARCH,go1.13 syscall_darwin.1_13.go |gofmt >zsyscall_$GOOSARCH.1_13.go";
|
|
||||||
elif [ "$GOOS" == "illumos" ]; then
|
elif [ "$GOOS" == "illumos" ]; then
|
||||||
# illumos code generation requires a --illumos switch
|
# illumos code generation requires a --illumos switch
|
||||||
echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go";
|
echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go";
|
||||||
@ -232,5 +245,5 @@ esac
|
|||||||
if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
|
if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
|
||||||
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
|
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
|
||||||
if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go"; fi
|
if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go"; fi
|
||||||
if [ -n "$mkasm" ]; then echo "$mkasm $GOARCH"; fi
|
if [ -n "$mkasm" ]; then echo "$mkasm $GOOS $GOARCH"; fi
|
||||||
) | $run
|
) | $run
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
@ -642,7 +642,7 @@ errors=$(
|
|||||||
signals=$(
|
signals=$(
|
||||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
|
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
|
||||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
|
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' |
|
||||||
sort
|
sort
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -652,7 +652,7 @@ echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
|
|||||||
sort >_error.grep
|
sort >_error.grep
|
||||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
||||||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
|
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' |
|
||||||
sort >_signal.grep
|
sort >_signal.grep
|
||||||
|
|
||||||
echo '// mkerrors.sh' "$@"
|
echo '// mkerrors.sh' "$@"
|
||||||
|
27
src/runtime/vendor/golang.org/x/sys/unix/str.go
generated
vendored
27
src/runtime/vendor/golang.org/x/sys/unix/str.go
generated
vendored
@ -1,27 +0,0 @@
|
|||||||
// Copyright 2009 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
func itoa(val int) string { // do it here rather than with fmt to avoid dependency
|
|
||||||
if val < 0 {
|
|
||||||
return "-" + uitoa(uint(-val))
|
|
||||||
}
|
|
||||||
return uitoa(uint(val))
|
|
||||||
}
|
|
||||||
|
|
||||||
func uitoa(val uint) string {
|
|
||||||
var buf [32]byte // big enough for int64
|
|
||||||
i := len(buf) - 1
|
|
||||||
for val >= 10 {
|
|
||||||
buf[i] = byte(val%10 + '0')
|
|
||||||
i--
|
|
||||||
val /= 10
|
|
||||||
}
|
|
||||||
buf[i] = byte(val + '0')
|
|
||||||
return string(buf[i:])
|
|
||||||
}
|
|
10
src/runtime/vendor/golang.org/x/sys/unix/syscall.go
generated
vendored
10
src/runtime/vendor/golang.org/x/sys/unix/syscall.go
generated
vendored
@ -29,8 +29,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/internal/unsafeheader"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ByteSliceFromString returns a NUL-terminated slice of bytes
|
// ByteSliceFromString returns a NUL-terminated slice of bytes
|
||||||
@ -82,13 +80,7 @@ func BytePtrToString(p *byte) string {
|
|||||||
ptr = unsafe.Pointer(uintptr(ptr) + 1)
|
ptr = unsafe.Pointer(uintptr(ptr) + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
var s []byte
|
return string(unsafe.Slice(p, n))
|
||||||
h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
|
|
||||||
h.Data = unsafe.Pointer(p)
|
|
||||||
h.Len = n
|
|
||||||
h.Cap = n
|
|
||||||
|
|
||||||
return string(s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Single-word zero for use when we need a valid pointer to 0 bytes.
|
// Single-word zero for use when we need a valid pointer to 0 bytes.
|
||||||
|
57
src/runtime/vendor/golang.org/x/sys/unix/syscall_aix.go
generated
vendored
57
src/runtime/vendor/golang.org/x/sys/unix/syscall_aix.go
generated
vendored
@ -218,13 +218,62 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
|
func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
|
||||||
// Recvmsg not implemented on AIX
|
var msg Msghdr
|
||||||
return -1, -1, -1, ENOSYS
|
msg.Name = (*byte)(unsafe.Pointer(rsa))
|
||||||
|
msg.Namelen = uint32(SizeofSockaddrAny)
|
||||||
|
var dummy byte
|
||||||
|
if len(oob) > 0 {
|
||||||
|
// receive at least one normal byte
|
||||||
|
if emptyIovecs(iov) {
|
||||||
|
var iova [1]Iovec
|
||||||
|
iova[0].Base = &dummy
|
||||||
|
iova[0].SetLen(1)
|
||||||
|
iov = iova[:]
|
||||||
|
}
|
||||||
|
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
|
||||||
|
msg.SetControllen(len(oob))
|
||||||
|
}
|
||||||
|
if len(iov) > 0 {
|
||||||
|
msg.Iov = &iov[0]
|
||||||
|
msg.SetIovlen(len(iov))
|
||||||
|
}
|
||||||
|
if n, err = recvmsg(fd, &msg, flags); n == -1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
oobn = int(msg.Controllen)
|
||||||
|
recvflags = int(msg.Flags)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
|
func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
|
||||||
// SendmsgN not implemented on AIX
|
var msg Msghdr
|
||||||
return -1, ENOSYS
|
msg.Name = (*byte)(unsafe.Pointer(ptr))
|
||||||
|
msg.Namelen = uint32(salen)
|
||||||
|
var dummy byte
|
||||||
|
var empty bool
|
||||||
|
if len(oob) > 0 {
|
||||||
|
// send at least one normal byte
|
||||||
|
empty = emptyIovecs(iov)
|
||||||
|
if empty {
|
||||||
|
var iova [1]Iovec
|
||||||
|
iova[0].Base = &dummy
|
||||||
|
iova[0].SetLen(1)
|
||||||
|
iov = iova[:]
|
||||||
|
}
|
||||||
|
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
|
||||||
|
msg.SetControllen(len(oob))
|
||||||
|
}
|
||||||
|
if len(iov) > 0 {
|
||||||
|
msg.Iov = &iov[0]
|
||||||
|
msg.SetIovlen(len(iov))
|
||||||
|
}
|
||||||
|
if n, err = sendmsg(fd, &msg, flags); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if len(oob) > 0 && empty {
|
||||||
|
n = 0
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
|
2
src/runtime/vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
2
src/runtime/vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
@ -363,7 +363,7 @@ func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Sockle
|
|||||||
var empty bool
|
var empty bool
|
||||||
if len(oob) > 0 {
|
if len(oob) > 0 {
|
||||||
// send at least one normal byte
|
// send at least one normal byte
|
||||||
empty := emptyIovecs(iov)
|
empty = emptyIovecs(iov)
|
||||||
if empty {
|
if empty {
|
||||||
var iova [1]Iovec
|
var iova [1]Iovec
|
||||||
iova[0].Base = &dummy
|
iova[0].Base = &dummy
|
||||||
|
32
src/runtime/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go
generated
vendored
32
src/runtime/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go
generated
vendored
@ -1,32 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
//go:build darwin && go1.12 && !go1.13
|
|
||||||
// +build darwin,go1.12,!go1.13
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const _SYS_GETDIRENTRIES64 = 344
|
|
||||||
|
|
||||||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
|
||||||
// To implement this using libSystem we'd need syscall_syscallPtr for
|
|
||||||
// fdopendir. However, syscallPtr was only added in Go 1.13, so we fall
|
|
||||||
// back to raw syscalls for this func on Go 1.12.
|
|
||||||
var p unsafe.Pointer
|
|
||||||
if len(buf) > 0 {
|
|
||||||
p = unsafe.Pointer(&buf[0])
|
|
||||||
} else {
|
|
||||||
p = unsafe.Pointer(&_zero)
|
|
||||||
}
|
|
||||||
r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES64, uintptr(fd), uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
|
|
||||||
n = int(r0)
|
|
||||||
if e1 != 0 {
|
|
||||||
return n, errnoErr(e1)
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
108
src/runtime/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go
generated
vendored
108
src/runtime/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go
generated
vendored
@ -1,108 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
//go:build darwin && go1.13
|
|
||||||
// +build darwin,go1.13
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/sys/internal/unsafeheader"
|
|
||||||
)
|
|
||||||
|
|
||||||
//sys closedir(dir uintptr) (err error)
|
|
||||||
//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
|
|
||||||
|
|
||||||
func fdopendir(fd int) (dir uintptr, err error) {
|
|
||||||
r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
|
|
||||||
dir = uintptr(r0)
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var libc_fdopendir_trampoline_addr uintptr
|
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
|
|
||||||
|
|
||||||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
|
||||||
// Simulate Getdirentries using fdopendir/readdir_r/closedir.
|
|
||||||
// We store the number of entries to skip in the seek
|
|
||||||
// offset of fd. See issue #31368.
|
|
||||||
// It's not the full required semantics, but should handle the case
|
|
||||||
// of calling Getdirentries or ReadDirent repeatedly.
|
|
||||||
// It won't handle assigning the results of lseek to *basep, or handle
|
|
||||||
// the directory being edited underfoot.
|
|
||||||
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need to duplicate the incoming file descriptor
|
|
||||||
// because the caller expects to retain control of it, but
|
|
||||||
// fdopendir expects to take control of its argument.
|
|
||||||
// Just Dup'ing the file descriptor is not enough, as the
|
|
||||||
// result shares underlying state. Use Openat to make a really
|
|
||||||
// new file descriptor referring to the same directory.
|
|
||||||
fd2, err := Openat(fd, ".", O_RDONLY, 0)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
d, err := fdopendir(fd2)
|
|
||||||
if err != nil {
|
|
||||||
Close(fd2)
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
defer closedir(d)
|
|
||||||
|
|
||||||
var cnt int64
|
|
||||||
for {
|
|
||||||
var entry Dirent
|
|
||||||
var entryp *Dirent
|
|
||||||
e := readdir_r(d, &entry, &entryp)
|
|
||||||
if e != 0 {
|
|
||||||
return n, errnoErr(e)
|
|
||||||
}
|
|
||||||
if entryp == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if skip > 0 {
|
|
||||||
skip--
|
|
||||||
cnt++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
reclen := int(entry.Reclen)
|
|
||||||
if reclen > len(buf) {
|
|
||||||
// Not enough room. Return for now.
|
|
||||||
// The counter will let us know where we should start up again.
|
|
||||||
// Note: this strategy for suspending in the middle and
|
|
||||||
// restarting is O(n^2) in the length of the directory. Oh well.
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy entry into return buffer.
|
|
||||||
var s []byte
|
|
||||||
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
|
|
||||||
hdr.Data = unsafe.Pointer(&entry)
|
|
||||||
hdr.Cap = reclen
|
|
||||||
hdr.Len = reclen
|
|
||||||
copy(buf, s)
|
|
||||||
|
|
||||||
buf = buf[reclen:]
|
|
||||||
n += reclen
|
|
||||||
cnt++
|
|
||||||
}
|
|
||||||
// Set the seek offset of the input fd to record
|
|
||||||
// how many files we've already returned.
|
|
||||||
_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
|
|
||||||
if err != nil {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return n, nil
|
|
||||||
}
|
|
90
src/runtime/vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
90
src/runtime/vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
@ -19,6 +19,96 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//sys closedir(dir uintptr) (err error)
|
||||||
|
//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
|
||||||
|
|
||||||
|
func fdopendir(fd int) (dir uintptr, err error) {
|
||||||
|
r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
|
||||||
|
dir = uintptr(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_fdopendir_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||||
|
// Simulate Getdirentries using fdopendir/readdir_r/closedir.
|
||||||
|
// We store the number of entries to skip in the seek
|
||||||
|
// offset of fd. See issue #31368.
|
||||||
|
// It's not the full required semantics, but should handle the case
|
||||||
|
// of calling Getdirentries or ReadDirent repeatedly.
|
||||||
|
// It won't handle assigning the results of lseek to *basep, or handle
|
||||||
|
// the directory being edited underfoot.
|
||||||
|
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to duplicate the incoming file descriptor
|
||||||
|
// because the caller expects to retain control of it, but
|
||||||
|
// fdopendir expects to take control of its argument.
|
||||||
|
// Just Dup'ing the file descriptor is not enough, as the
|
||||||
|
// result shares underlying state. Use Openat to make a really
|
||||||
|
// new file descriptor referring to the same directory.
|
||||||
|
fd2, err := Openat(fd, ".", O_RDONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
d, err := fdopendir(fd2)
|
||||||
|
if err != nil {
|
||||||
|
Close(fd2)
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer closedir(d)
|
||||||
|
|
||||||
|
var cnt int64
|
||||||
|
for {
|
||||||
|
var entry Dirent
|
||||||
|
var entryp *Dirent
|
||||||
|
e := readdir_r(d, &entry, &entryp)
|
||||||
|
if e != 0 {
|
||||||
|
return n, errnoErr(e)
|
||||||
|
}
|
||||||
|
if entryp == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if skip > 0 {
|
||||||
|
skip--
|
||||||
|
cnt++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
reclen := int(entry.Reclen)
|
||||||
|
if reclen > len(buf) {
|
||||||
|
// Not enough room. Return for now.
|
||||||
|
// The counter will let us know where we should start up again.
|
||||||
|
// Note: this strategy for suspending in the middle and
|
||||||
|
// restarting is O(n^2) in the length of the directory. Oh well.
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy entry into return buffer.
|
||||||
|
s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
|
||||||
|
copy(buf, s)
|
||||||
|
|
||||||
|
buf = buf[reclen:]
|
||||||
|
n += reclen
|
||||||
|
cnt++
|
||||||
|
}
|
||||||
|
// Set the seek offset of the input fd to record
|
||||||
|
// how many files we've already returned.
|
||||||
|
_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
|
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
|
||||||
type SockaddrDatalink struct {
|
type SockaddrDatalink struct {
|
||||||
Len uint8
|
Len uint8
|
||||||
|
2
src/runtime/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go
generated
vendored
2
src/runtime/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go
generated
vendored
@ -61,7 +61,7 @@ func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
|
ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint32(countin)}
|
||||||
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||||
return int(ioDesc.Len), err
|
return int(ioDesc.Len), err
|
||||||
}
|
}
|
||||||
|
2
src/runtime/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go
generated
vendored
2
src/runtime/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go
generated
vendored
@ -61,7 +61,7 @@ func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
||||||
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||||
return int(ioDesc.Len), err
|
return int(ioDesc.Len), err
|
||||||
}
|
}
|
||||||
|
2
src/runtime/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go
generated
vendored
2
src/runtime/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go
generated
vendored
@ -57,7 +57,7 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
|||||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||||
|
|
||||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
|
ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint32(countin)}
|
||||||
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||||
return int(ioDesc.Len), err
|
return int(ioDesc.Len), err
|
||||||
}
|
}
|
||||||
|
2
src/runtime/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go
generated
vendored
2
src/runtime/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go
generated
vendored
@ -57,7 +57,7 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
|||||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||||
|
|
||||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
||||||
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||||
return int(ioDesc.Len), err
|
return int(ioDesc.Len), err
|
||||||
}
|
}
|
||||||
|
2
src/runtime/vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go
generated
vendored
2
src/runtime/vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go
generated
vendored
@ -57,7 +57,7 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
|||||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||||
|
|
||||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
||||||
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||||
return int(ioDesc.Len), err
|
return int(ioDesc.Len), err
|
||||||
}
|
}
|
||||||
|
106
src/runtime/vendor/golang.org/x/sys/unix/syscall_illumos.go
generated
vendored
106
src/runtime/vendor/golang.org/x/sys/unix/syscall_illumos.go
generated
vendored
@ -10,8 +10,6 @@
|
|||||||
package unix
|
package unix
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -79,107 +77,3 @@ func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error)
|
|
||||||
|
|
||||||
func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) {
|
|
||||||
var clp, datap *strbuf
|
|
||||||
if len(cl) > 0 {
|
|
||||||
clp = &strbuf{
|
|
||||||
Len: int32(len(cl)),
|
|
||||||
Buf: (*int8)(unsafe.Pointer(&cl[0])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(data) > 0 {
|
|
||||||
datap = &strbuf{
|
|
||||||
Len: int32(len(data)),
|
|
||||||
Buf: (*int8)(unsafe.Pointer(&data[0])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return putmsg(fd, clp, datap, flags)
|
|
||||||
}
|
|
||||||
|
|
||||||
//sys getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error)
|
|
||||||
|
|
||||||
func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) {
|
|
||||||
var clp, datap *strbuf
|
|
||||||
if len(cl) > 0 {
|
|
||||||
clp = &strbuf{
|
|
||||||
Maxlen: int32(len(cl)),
|
|
||||||
Buf: (*int8)(unsafe.Pointer(&cl[0])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(data) > 0 {
|
|
||||||
datap = &strbuf{
|
|
||||||
Maxlen: int32(len(data)),
|
|
||||||
Buf: (*int8)(unsafe.Pointer(&data[0])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = getmsg(fd, clp, datap, &flags); err != nil {
|
|
||||||
return nil, nil, 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cl) > 0 {
|
|
||||||
retCl = cl[:clp.Len]
|
|
||||||
}
|
|
||||||
if len(data) > 0 {
|
|
||||||
retData = data[:datap.Len]
|
|
||||||
}
|
|
||||||
return retCl, retData, flags, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) {
|
|
||||||
return ioctlRet(fd, req, uintptr(arg))
|
|
||||||
}
|
|
||||||
|
|
||||||
func IoctlSetString(fd int, req uint, val string) error {
|
|
||||||
bs := make([]byte, len(val)+1)
|
|
||||||
copy(bs[:len(bs)-1], val)
|
|
||||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0])))
|
|
||||||
runtime.KeepAlive(&bs[0])
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lifreq Helpers
|
|
||||||
|
|
||||||
func (l *Lifreq) SetName(name string) error {
|
|
||||||
if len(name) >= len(l.Name) {
|
|
||||||
return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
|
|
||||||
}
|
|
||||||
for i := range name {
|
|
||||||
l.Name[i] = int8(name[i])
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lifreq) SetLifruInt(d int) {
|
|
||||||
*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lifreq) GetLifruInt() int {
|
|
||||||
return *(*int)(unsafe.Pointer(&l.Lifru[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lifreq) SetLifruUint(d uint) {
|
|
||||||
*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lifreq) GetLifruUint() uint {
|
|
||||||
return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
func IoctlLifreq(fd int, req uint, l *Lifreq) error {
|
|
||||||
return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strioctl Helpers
|
|
||||||
|
|
||||||
func (s *Strioctl) SetInt(i int) {
|
|
||||||
s.Len = int32(unsafe.Sizeof(i))
|
|
||||||
s.Dp = (*int8)(unsafe.Pointer(&i))
|
|
||||||
}
|
|
||||||
|
|
||||||
func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) {
|
|
||||||
return ioctlRet(fd, req, uintptr(unsafe.Pointer(s)))
|
|
||||||
}
|
|
||||||
|
45
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
45
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
@ -13,6 +13,7 @@ package unix
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
@ -233,7 +234,7 @@ func Futimesat(dirfd int, path string, tv []Timeval) error {
|
|||||||
func Futimes(fd int, tv []Timeval) (err error) {
|
func Futimes(fd int, tv []Timeval) (err error) {
|
||||||
// Believe it or not, this is the best we can do on Linux
|
// Believe it or not, this is the best we can do on Linux
|
||||||
// (and is what glibc does).
|
// (and is what glibc does).
|
||||||
return Utimes("/proc/self/fd/"+itoa(fd), tv)
|
return Utimes("/proc/self/fd/"+strconv.Itoa(fd), tv)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ImplementsGetwd = true
|
const ImplementsGetwd = true
|
||||||
@ -1541,7 +1542,7 @@ func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Sockle
|
|||||||
var dummy byte
|
var dummy byte
|
||||||
var empty bool
|
var empty bool
|
||||||
if len(oob) > 0 {
|
if len(oob) > 0 {
|
||||||
empty := emptyIovecs(iov)
|
empty = emptyIovecs(iov)
|
||||||
if empty {
|
if empty {
|
||||||
var sockType int
|
var sockType int
|
||||||
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
|
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
|
||||||
@ -1891,17 +1892,28 @@ func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uint
|
|||||||
return int(ret), nil
|
return int(ret), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// issue 1435.
|
|
||||||
// On linux Setuid and Setgid only affects the current thread, not the process.
|
|
||||||
// This does not match what most callers expect so we must return an error
|
|
||||||
// here rather than letting the caller think that the call succeeded.
|
|
||||||
|
|
||||||
func Setuid(uid int) (err error) {
|
func Setuid(uid int) (err error) {
|
||||||
return EOPNOTSUPP
|
return syscall.Setuid(uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Setgid(uid int) (err error) {
|
func Setgid(gid int) (err error) {
|
||||||
return EOPNOTSUPP
|
return syscall.Setgid(gid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setreuid(ruid, euid int) (err error) {
|
||||||
|
return syscall.Setreuid(ruid, euid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setregid(rgid, egid int) (err error) {
|
||||||
|
return syscall.Setregid(rgid, egid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setresuid(ruid, euid, suid int) (err error) {
|
||||||
|
return syscall.Setresuid(ruid, euid, suid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setresgid(rgid, egid, sgid int) (err error) {
|
||||||
|
return syscall.Setresgid(rgid, egid, sgid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set.
|
// SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set.
|
||||||
@ -2240,7 +2252,7 @@ func (fh *FileHandle) Bytes() []byte {
|
|||||||
if n == 0 {
|
if n == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return (*[1 << 30]byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type)) + 4))[:n:n]
|
return unsafe.Slice((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type))+4)), n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NameToHandleAt wraps the name_to_handle_at system call; it obtains
|
// NameToHandleAt wraps the name_to_handle_at system call; it obtains
|
||||||
@ -2356,6 +2368,16 @@ func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
|
|||||||
return prev, nil
|
return prev, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//sysnb rtSigprocmask(how int, set *Sigset_t, oldset *Sigset_t, sigsetsize uintptr) (err error) = SYS_RT_SIGPROCMASK
|
||||||
|
|
||||||
|
func PthreadSigmask(how int, set, oldset *Sigset_t) error {
|
||||||
|
if oldset != nil {
|
||||||
|
// Explicitly clear in case Sigset_t is larger than _C__NSIG.
|
||||||
|
*oldset = Sigset_t{}
|
||||||
|
}
|
||||||
|
return rtSigprocmask(how, set, oldset, _C__NSIG/8)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unimplemented
|
* Unimplemented
|
||||||
*/
|
*/
|
||||||
@ -2414,7 +2436,6 @@ func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
|
|||||||
// RestartSyscall
|
// RestartSyscall
|
||||||
// RtSigaction
|
// RtSigaction
|
||||||
// RtSigpending
|
// RtSigpending
|
||||||
// RtSigprocmask
|
|
||||||
// RtSigqueueinfo
|
// RtSigqueueinfo
|
||||||
// RtSigreturn
|
// RtSigreturn
|
||||||
// RtSigsuspend
|
// RtSigsuspend
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_386.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_386.go
generated
vendored
@ -41,10 +41,6 @@ func setTimeval(sec, usec int64) Timeval {
|
|||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||||
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
|
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
|
||||||
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
|
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
|
||||||
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
|
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
|
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
||||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||||
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
generated
vendored
@ -46,11 +46,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
|||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
|
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
generated
vendored
@ -62,10 +62,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
|||||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
||||||
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
|
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
|
||||||
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
|
//sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
|
||||||
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
|
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
||||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
generated
vendored
@ -39,11 +39,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
|||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
|
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go
generated
vendored
@ -34,10 +34,6 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
|||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
|
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
generated
vendored
@ -37,11 +37,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
|||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
//sys Statfs(path string, buf *Statfs_t) (err error)
|
//sys Statfs(path string, buf *Statfs_t) (err error)
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
generated
vendored
@ -32,10 +32,6 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
|
|||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
||||||
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
generated
vendored
@ -34,10 +34,6 @@ import (
|
|||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
||||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
generated
vendored
@ -34,11 +34,7 @@ package unix
|
|||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
//sys Stat(path string, stat *Stat_t) (err error)
|
//sys Stat(path string, stat *Stat_t) (err error)
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
generated
vendored
@ -38,11 +38,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
|||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
|
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
generated
vendored
@ -34,11 +34,7 @@ import (
|
|||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
//sys Stat(path string, stat *Stat_t) (err error)
|
//sys Stat(path string, stat *Stat_t) (err error)
|
||||||
//sys Statfs(path string, buf *Statfs_t) (err error)
|
//sys Statfs(path string, buf *Statfs_t) (err error)
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
generated
vendored
@ -31,11 +31,7 @@ package unix
|
|||||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
//sys setfsgid(gid int) (prev int, err error)
|
//sys setfsgid(gid int) (prev int, err error)
|
||||||
//sys setfsuid(uid int) (prev int, err error)
|
//sys setfsuid(uid int) (prev int, err error)
|
||||||
//sysnb Setregid(rgid int, egid int) (err error)
|
|
||||||
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
|
||||||
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
|
||||||
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
//sysnb Setreuid(ruid int, euid int) (err error)
|
|
||||||
//sys Shutdown(fd int, how int) (err error)
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
//sys Stat(path string, stat *Stat_t) (err error)
|
//sys Stat(path string, stat *Stat_t) (err error)
|
||||||
|
27
src/runtime/vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go
generated
vendored
Normal file
27
src/runtime/vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2022 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build openbsd && !mips64
|
||||||
|
// +build openbsd,!mips64
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import _ "unsafe"
|
||||||
|
|
||||||
|
// Implemented in the runtime package (runtime/sys_openbsd3.go)
|
||||||
|
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
func syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||||
|
|
||||||
|
//go:linkname syscall_syscall syscall.syscall
|
||||||
|
//go:linkname syscall_syscall6 syscall.syscall6
|
||||||
|
//go:linkname syscall_syscall10 syscall.syscall10
|
||||||
|
//go:linkname syscall_rawSyscall syscall.rawSyscall
|
||||||
|
//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
|
||||||
|
|
||||||
|
func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) {
|
||||||
|
return syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, 0)
|
||||||
|
}
|
42
src/runtime/vendor/golang.org/x/sys/unix/syscall_openbsd_ppc64.go
generated
vendored
Normal file
42
src/runtime/vendor/golang.org/x/sys/unix/syscall_openbsd_ppc64.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build ppc64 && openbsd
|
||||||
|
// +build ppc64,openbsd
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
func setTimespec(sec, nsec int64) Timespec {
|
||||||
|
return Timespec{Sec: sec, Nsec: nsec}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setTimeval(sec, usec int64) Timeval {
|
||||||
|
return Timeval{Sec: sec, Usec: usec}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint64(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetIovlen(length int) {
|
||||||
|
msghdr.Iovlen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
|
||||||
|
// of openbsd/ppc64 the syscall is called sysctl instead of __sysctl.
|
||||||
|
const SYS___SYSCTL = SYS_SYSCTL
|
42
src/runtime/vendor/golang.org/x/sys/unix/syscall_openbsd_riscv64.go
generated
vendored
Normal file
42
src/runtime/vendor/golang.org/x/sys/unix/syscall_openbsd_riscv64.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build riscv64 && openbsd
|
||||||
|
// +build riscv64,openbsd
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
func setTimespec(sec, nsec int64) Timespec {
|
||||||
|
return Timespec{Sec: sec, Nsec: nsec}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setTimeval(sec, usec int64) Timeval {
|
||||||
|
return Timeval{Sec: sec, Usec: usec}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint64(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetIovlen(length int) {
|
||||||
|
msghdr.Iovlen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
|
||||||
|
// of openbsd/riscv64 the syscall is called sysctl instead of __sysctl.
|
||||||
|
const SYS___SYSCTL = SYS_SYSCTL
|
215
src/runtime/vendor/golang.org/x/sys/unix/syscall_solaris.go
generated
vendored
215
src/runtime/vendor/golang.org/x/sys/unix/syscall_solaris.go
generated
vendored
@ -750,8 +750,8 @@ type EventPort struct {
|
|||||||
// we should handle things gracefully. To do so, we need to keep an extra
|
// we should handle things gracefully. To do so, we need to keep an extra
|
||||||
// reference to the cookie around until the event is processed
|
// reference to the cookie around until the event is processed
|
||||||
// thus the otherwise seemingly extraneous "cookies" map
|
// thus the otherwise seemingly extraneous "cookies" map
|
||||||
// The key of this map is a pointer to the corresponding &fCookie.cookie
|
// The key of this map is a pointer to the corresponding fCookie
|
||||||
cookies map[*interface{}]*fileObjCookie
|
cookies map[*fileObjCookie]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PortEvent is an abstraction of the port_event C struct.
|
// PortEvent is an abstraction of the port_event C struct.
|
||||||
@ -778,7 +778,7 @@ func NewEventPort() (*EventPort, error) {
|
|||||||
port: port,
|
port: port,
|
||||||
fds: make(map[uintptr]*fileObjCookie),
|
fds: make(map[uintptr]*fileObjCookie),
|
||||||
paths: make(map[string]*fileObjCookie),
|
paths: make(map[string]*fileObjCookie),
|
||||||
cookies: make(map[*interface{}]*fileObjCookie),
|
cookies: make(map[*fileObjCookie]struct{}),
|
||||||
}
|
}
|
||||||
return e, nil
|
return e, nil
|
||||||
}
|
}
|
||||||
@ -799,6 +799,7 @@ func (e *EventPort) Close() error {
|
|||||||
}
|
}
|
||||||
e.fds = nil
|
e.fds = nil
|
||||||
e.paths = nil
|
e.paths = nil
|
||||||
|
e.cookies = nil
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -826,17 +827,16 @@ func (e *EventPort) AssociatePath(path string, stat os.FileInfo, events int, coo
|
|||||||
if _, found := e.paths[path]; found {
|
if _, found := e.paths[path]; found {
|
||||||
return fmt.Errorf("%v is already associated with this Event Port", path)
|
return fmt.Errorf("%v is already associated with this Event Port", path)
|
||||||
}
|
}
|
||||||
fobj, err := createFileObj(path, stat)
|
fCookie, err := createFileObjCookie(path, stat, cookie)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fCookie := &fileObjCookie{fobj, cookie}
|
_, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fCookie.fobj)), events, (*byte)(unsafe.Pointer(fCookie)))
|
||||||
_, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fobj)), events, (*byte)(unsafe.Pointer(&fCookie.cookie)))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
e.paths[path] = fCookie
|
e.paths[path] = fCookie
|
||||||
e.cookies[&fCookie.cookie] = fCookie
|
e.cookies[fCookie] = struct{}{}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -858,7 +858,7 @@ func (e *EventPort) DissociatePath(path string) error {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
// dissociate was successful, safe to delete the cookie
|
// dissociate was successful, safe to delete the cookie
|
||||||
fCookie := e.paths[path]
|
fCookie := e.paths[path]
|
||||||
delete(e.cookies, &fCookie.cookie)
|
delete(e.cookies, fCookie)
|
||||||
}
|
}
|
||||||
delete(e.paths, path)
|
delete(e.paths, path)
|
||||||
return err
|
return err
|
||||||
@ -871,13 +871,16 @@ func (e *EventPort) AssociateFd(fd uintptr, events int, cookie interface{}) erro
|
|||||||
if _, found := e.fds[fd]; found {
|
if _, found := e.fds[fd]; found {
|
||||||
return fmt.Errorf("%v is already associated with this Event Port", fd)
|
return fmt.Errorf("%v is already associated with this Event Port", fd)
|
||||||
}
|
}
|
||||||
fCookie := &fileObjCookie{nil, cookie}
|
fCookie, err := createFileObjCookie("", nil, cookie)
|
||||||
_, err := port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(&fCookie.cookie)))
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(fCookie)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
e.fds[fd] = fCookie
|
e.fds[fd] = fCookie
|
||||||
e.cookies[&fCookie.cookie] = fCookie
|
e.cookies[fCookie] = struct{}{}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -896,27 +899,31 @@ func (e *EventPort) DissociateFd(fd uintptr) error {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
// dissociate was successful, safe to delete the cookie
|
// dissociate was successful, safe to delete the cookie
|
||||||
fCookie := e.fds[fd]
|
fCookie := e.fds[fd]
|
||||||
delete(e.cookies, &fCookie.cookie)
|
delete(e.cookies, fCookie)
|
||||||
}
|
}
|
||||||
delete(e.fds, fd)
|
delete(e.fds, fd)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func createFileObj(name string, stat os.FileInfo) (*fileObj, error) {
|
func createFileObjCookie(name string, stat os.FileInfo, cookie interface{}) (*fileObjCookie, error) {
|
||||||
fobj := new(fileObj)
|
fCookie := new(fileObjCookie)
|
||||||
bs, err := ByteSliceFromString(name)
|
fCookie.cookie = cookie
|
||||||
if err != nil {
|
if name != "" && stat != nil {
|
||||||
return nil, err
|
fCookie.fobj = new(fileObj)
|
||||||
|
bs, err := ByteSliceFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fCookie.fobj.Name = (*int8)(unsafe.Pointer(&bs[0]))
|
||||||
|
s := stat.Sys().(*syscall.Stat_t)
|
||||||
|
fCookie.fobj.Atim.Sec = s.Atim.Sec
|
||||||
|
fCookie.fobj.Atim.Nsec = s.Atim.Nsec
|
||||||
|
fCookie.fobj.Mtim.Sec = s.Mtim.Sec
|
||||||
|
fCookie.fobj.Mtim.Nsec = s.Mtim.Nsec
|
||||||
|
fCookie.fobj.Ctim.Sec = s.Ctim.Sec
|
||||||
|
fCookie.fobj.Ctim.Nsec = s.Ctim.Nsec
|
||||||
}
|
}
|
||||||
fobj.Name = (*int8)(unsafe.Pointer(&bs[0]))
|
return fCookie, nil
|
||||||
s := stat.Sys().(*syscall.Stat_t)
|
|
||||||
fobj.Atim.Sec = s.Atim.Sec
|
|
||||||
fobj.Atim.Nsec = s.Atim.Nsec
|
|
||||||
fobj.Mtim.Sec = s.Mtim.Sec
|
|
||||||
fobj.Mtim.Nsec = s.Mtim.Nsec
|
|
||||||
fobj.Ctim.Sec = s.Ctim.Sec
|
|
||||||
fobj.Ctim.Nsec = s.Ctim.Nsec
|
|
||||||
return fobj, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOne wraps port_get(3c) and returns a single PortEvent.
|
// GetOne wraps port_get(3c) and returns a single PortEvent.
|
||||||
@ -929,44 +936,50 @@ func (e *EventPort) GetOne(t *Timespec) (*PortEvent, error) {
|
|||||||
p := new(PortEvent)
|
p := new(PortEvent)
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
defer e.mu.Unlock()
|
defer e.mu.Unlock()
|
||||||
e.peIntToExt(pe, p)
|
err = e.peIntToExt(pe, p)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// peIntToExt converts a cgo portEvent struct into the friendlier PortEvent
|
// peIntToExt converts a cgo portEvent struct into the friendlier PortEvent
|
||||||
// NOTE: Always call this function while holding the e.mu mutex
|
// NOTE: Always call this function while holding the e.mu mutex
|
||||||
func (e *EventPort) peIntToExt(peInt *portEvent, peExt *PortEvent) {
|
func (e *EventPort) peIntToExt(peInt *portEvent, peExt *PortEvent) error {
|
||||||
|
if e.cookies == nil {
|
||||||
|
return fmt.Errorf("this EventPort is already closed")
|
||||||
|
}
|
||||||
peExt.Events = peInt.Events
|
peExt.Events = peInt.Events
|
||||||
peExt.Source = peInt.Source
|
peExt.Source = peInt.Source
|
||||||
cookie := (*interface{})(unsafe.Pointer(peInt.User))
|
fCookie := (*fileObjCookie)(unsafe.Pointer(peInt.User))
|
||||||
peExt.Cookie = *cookie
|
_, found := e.cookies[fCookie]
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
panic("unexpected event port address; may be due to kernel bug; see https://go.dev/issue/54254")
|
||||||
|
}
|
||||||
|
peExt.Cookie = fCookie.cookie
|
||||||
|
delete(e.cookies, fCookie)
|
||||||
|
|
||||||
switch peInt.Source {
|
switch peInt.Source {
|
||||||
case PORT_SOURCE_FD:
|
case PORT_SOURCE_FD:
|
||||||
delete(e.cookies, cookie)
|
|
||||||
peExt.Fd = uintptr(peInt.Object)
|
peExt.Fd = uintptr(peInt.Object)
|
||||||
// Only remove the fds entry if it exists and this cookie matches
|
// Only remove the fds entry if it exists and this cookie matches
|
||||||
if fobj, ok := e.fds[peExt.Fd]; ok {
|
if fobj, ok := e.fds[peExt.Fd]; ok {
|
||||||
if &fobj.cookie == cookie {
|
if fobj == fCookie {
|
||||||
delete(e.fds, peExt.Fd)
|
delete(e.fds, peExt.Fd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case PORT_SOURCE_FILE:
|
case PORT_SOURCE_FILE:
|
||||||
if fCookie, ok := e.cookies[cookie]; ok && uintptr(unsafe.Pointer(fCookie.fobj)) == uintptr(peInt.Object) {
|
peExt.fobj = fCookie.fobj
|
||||||
// Use our stashed reference rather than using unsafe on what we got back
|
|
||||||
// the unsafe version would be (*fileObj)(unsafe.Pointer(uintptr(peInt.Object)))
|
|
||||||
peExt.fobj = fCookie.fobj
|
|
||||||
} else {
|
|
||||||
panic("mismanaged memory")
|
|
||||||
}
|
|
||||||
delete(e.cookies, cookie)
|
|
||||||
peExt.Path = BytePtrToString((*byte)(unsafe.Pointer(peExt.fobj.Name)))
|
peExt.Path = BytePtrToString((*byte)(unsafe.Pointer(peExt.fobj.Name)))
|
||||||
// Only remove the paths entry if it exists and this cookie matches
|
// Only remove the paths entry if it exists and this cookie matches
|
||||||
if fobj, ok := e.paths[peExt.Path]; ok {
|
if fobj, ok := e.paths[peExt.Path]; ok {
|
||||||
if &fobj.cookie == cookie {
|
if fobj == fCookie {
|
||||||
delete(e.paths, peExt.Path)
|
delete(e.paths, peExt.Path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pending wraps port_getn(3c) and returns how many events are pending.
|
// Pending wraps port_getn(3c) and returns how many events are pending.
|
||||||
@ -990,7 +1003,7 @@ func (e *EventPort) Get(s []PortEvent, min int, timeout *Timespec) (int, error)
|
|||||||
got := uint32(min)
|
got := uint32(min)
|
||||||
max := uint32(len(s))
|
max := uint32(len(s))
|
||||||
var err error
|
var err error
|
||||||
ps := make([]portEvent, max, max)
|
ps := make([]portEvent, max)
|
||||||
_, err = port_getn(e.port, &ps[0], max, &got, timeout)
|
_, err = port_getn(e.port, &ps[0], max, &got, timeout)
|
||||||
// got will be trustworthy with ETIME, but not any other error.
|
// got will be trustworthy with ETIME, but not any other error.
|
||||||
if err != nil && err != ETIME {
|
if err != nil && err != ETIME {
|
||||||
@ -998,8 +1011,122 @@ func (e *EventPort) Get(s []PortEvent, min int, timeout *Timespec) (int, error)
|
|||||||
}
|
}
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
defer e.mu.Unlock()
|
defer e.mu.Unlock()
|
||||||
|
valid := 0
|
||||||
for i := 0; i < int(got); i++ {
|
for i := 0; i < int(got); i++ {
|
||||||
e.peIntToExt(&ps[i], &s[i])
|
err2 := e.peIntToExt(&ps[i], &s[i])
|
||||||
|
if err2 != nil {
|
||||||
|
if valid == 0 && err == nil {
|
||||||
|
// If err2 is the only error and there are no valid events
|
||||||
|
// to return, return it to the caller.
|
||||||
|
err = err2
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
valid = i + 1
|
||||||
}
|
}
|
||||||
return int(got), err
|
return valid, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error)
|
||||||
|
|
||||||
|
func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) {
|
||||||
|
var clp, datap *strbuf
|
||||||
|
if len(cl) > 0 {
|
||||||
|
clp = &strbuf{
|
||||||
|
Len: int32(len(cl)),
|
||||||
|
Buf: (*int8)(unsafe.Pointer(&cl[0])),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(data) > 0 {
|
||||||
|
datap = &strbuf{
|
||||||
|
Len: int32(len(data)),
|
||||||
|
Buf: (*int8)(unsafe.Pointer(&data[0])),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return putmsg(fd, clp, datap, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error)
|
||||||
|
|
||||||
|
func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) {
|
||||||
|
var clp, datap *strbuf
|
||||||
|
if len(cl) > 0 {
|
||||||
|
clp = &strbuf{
|
||||||
|
Maxlen: int32(len(cl)),
|
||||||
|
Buf: (*int8)(unsafe.Pointer(&cl[0])),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(data) > 0 {
|
||||||
|
datap = &strbuf{
|
||||||
|
Maxlen: int32(len(data)),
|
||||||
|
Buf: (*int8)(unsafe.Pointer(&data[0])),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = getmsg(fd, clp, datap, &flags); err != nil {
|
||||||
|
return nil, nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cl) > 0 {
|
||||||
|
retCl = cl[:clp.Len]
|
||||||
|
}
|
||||||
|
if len(data) > 0 {
|
||||||
|
retData = data[:datap.Len]
|
||||||
|
}
|
||||||
|
return retCl, retData, flags, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) {
|
||||||
|
return ioctlRet(fd, req, uintptr(arg))
|
||||||
|
}
|
||||||
|
|
||||||
|
func IoctlSetString(fd int, req uint, val string) error {
|
||||||
|
bs := make([]byte, len(val)+1)
|
||||||
|
copy(bs[:len(bs)-1], val)
|
||||||
|
err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0])))
|
||||||
|
runtime.KeepAlive(&bs[0])
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lifreq Helpers
|
||||||
|
|
||||||
|
func (l *Lifreq) SetName(name string) error {
|
||||||
|
if len(name) >= len(l.Name) {
|
||||||
|
return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
|
||||||
|
}
|
||||||
|
for i := range name {
|
||||||
|
l.Name[i] = int8(name[i])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lifreq) SetLifruInt(d int) {
|
||||||
|
*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lifreq) GetLifruInt() int {
|
||||||
|
return *(*int)(unsafe.Pointer(&l.Lifru[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lifreq) SetLifruUint(d uint) {
|
||||||
|
*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Lifreq) GetLifruUint() uint {
|
||||||
|
return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func IoctlLifreq(fd int, req uint, l *Lifreq) error {
|
||||||
|
return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strioctl Helpers
|
||||||
|
|
||||||
|
func (s *Strioctl) SetInt(i int) {
|
||||||
|
s.Len = int32(unsafe.Sizeof(i))
|
||||||
|
s.Dp = (*int8)(unsafe.Pointer(&i))
|
||||||
|
}
|
||||||
|
|
||||||
|
func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) {
|
||||||
|
return ioctlRet(fd, req, uintptr(unsafe.Pointer(s)))
|
||||||
}
|
}
|
||||||
|
20
src/runtime/vendor/golang.org/x/sys/unix/syscall_unix.go
generated
vendored
20
src/runtime/vendor/golang.org/x/sys/unix/syscall_unix.go
generated
vendored
@ -13,8 +13,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/internal/unsafeheader"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -117,11 +115,7 @@ func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (d
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use unsafe to convert addr into a []byte.
|
// Use unsafe to convert addr into a []byte.
|
||||||
var b []byte
|
b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length)
|
||||||
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
|
|
||||||
hdr.Data = unsafe.Pointer(addr)
|
|
||||||
hdr.Cap = length
|
|
||||||
hdr.Len = length
|
|
||||||
|
|
||||||
// Register mapping in m and return it.
|
// Register mapping in m and return it.
|
||||||
p := &b[cap(b)-1]
|
p := &b[cap(b)-1]
|
||||||
@ -429,11 +423,15 @@ func Send(s int, buf []byte, flags int) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
|
func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
|
||||||
ptr, n, err := to.sockaddr()
|
var ptr unsafe.Pointer
|
||||||
if err != nil {
|
var salen _Socklen
|
||||||
return err
|
if to != nil {
|
||||||
|
ptr, salen, err = to.sockaddr()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return sendto(fd, p, flags, ptr, n)
|
return sendto(fd, p, flags, ptr, salen)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetsockoptByte(fd, level, opt int, value byte) (err error) {
|
func SetsockoptByte(fd, level, opt int, value byte) (err error) {
|
||||||
|
6
src/runtime/vendor/golang.org/x/sys/unix/syscall_unix_gc.go
generated
vendored
6
src/runtime/vendor/golang.org/x/sys/unix/syscall_unix_gc.go
generated
vendored
@ -2,11 +2,9 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build (darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris) && gc && !ppc64le && !ppc64
|
//go:build (darwin || dragonfly || freebsd || (linux && !ppc64 && !ppc64le) || netbsd || openbsd || solaris) && gc
|
||||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
// +build darwin dragonfly freebsd linux,!ppc64,!ppc64le netbsd openbsd solaris
|
||||||
// +build gc
|
// +build gc
|
||||||
// +build !ppc64le
|
|
||||||
// +build !ppc64
|
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
173
src/runtime/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
generated
vendored
173
src/runtime/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
generated
vendored
@ -9,8 +9,10 @@ package unix
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
@ -55,7 +57,13 @@ func (d *Dirent) NameString() string {
|
|||||||
if d == nil {
|
if d == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return string(d.Name[:d.Namlen])
|
s := string(d.Name[:])
|
||||||
|
idx := strings.IndexByte(s, 0)
|
||||||
|
if idx == -1 {
|
||||||
|
return s
|
||||||
|
} else {
|
||||||
|
return s[:idx]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
@ -1230,6 +1238,14 @@ func Readdir(dir uintptr) (*Dirent, error) {
|
|||||||
return &ent, err
|
return &ent, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readdir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) {
|
||||||
|
r0, _, e1 := syscall_syscall(SYS___READDIR_R_A, dirp, uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
|
||||||
|
if int64(r0) == -1 {
|
||||||
|
err = errnoErr(Errno(e1))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func Closedir(dir uintptr) error {
|
func Closedir(dir uintptr) error {
|
||||||
_, _, e := syscall_syscall(SYS_CLOSEDIR, dir, 0, 0)
|
_, _, e := syscall_syscall(SYS_CLOSEDIR, dir, 0, 0)
|
||||||
if e != 0 {
|
if e != 0 {
|
||||||
@ -1821,3 +1837,158 @@ func Unmount(name string, mtm int) (err error) {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fdToPath(dirfd int) (path string, err error) {
|
||||||
|
var buffer [1024]byte
|
||||||
|
// w_ctrl()
|
||||||
|
ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
|
||||||
|
[]uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
|
||||||
|
if ret == 0 {
|
||||||
|
zb := bytes.IndexByte(buffer[:], 0)
|
||||||
|
if zb == -1 {
|
||||||
|
zb = len(buffer)
|
||||||
|
}
|
||||||
|
// __e2a_l()
|
||||||
|
runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
|
||||||
|
[]uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
|
||||||
|
return string(buffer[:zb]), nil
|
||||||
|
}
|
||||||
|
// __errno()
|
||||||
|
errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
|
||||||
|
[]uintptr{}))))
|
||||||
|
// __errno2()
|
||||||
|
errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
|
||||||
|
[]uintptr{}))
|
||||||
|
// strerror_r()
|
||||||
|
ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
|
||||||
|
[]uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
|
||||||
|
if ret == 0 {
|
||||||
|
zb := bytes.IndexByte(buffer[:], 0)
|
||||||
|
if zb == -1 {
|
||||||
|
zb = len(buffer)
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {
|
||||||
|
var d Dirent
|
||||||
|
|
||||||
|
d.Ino = uint64(dirent.Ino)
|
||||||
|
offset, err := Telldir(dir)
|
||||||
|
if err != nil {
|
||||||
|
return d, err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Off = int64(offset)
|
||||||
|
s := string(bytes.Split(dirent.Name[:], []byte{0})[0])
|
||||||
|
copy(d.Name[:], s)
|
||||||
|
|
||||||
|
d.Reclen = uint16(24 + len(d.NameString()))
|
||||||
|
var st Stat_t
|
||||||
|
path = path + "/" + s
|
||||||
|
err = Lstat(path, &st)
|
||||||
|
if err != nil {
|
||||||
|
return d, err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Type = uint8(st.Mode >> 24)
|
||||||
|
return d, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||||
|
// Simulation of Getdirentries port from the Darwin implementation.
|
||||||
|
// COMMENTS FROM DARWIN:
|
||||||
|
// It's not the full required semantics, but should handle the case
|
||||||
|
// of calling Getdirentries or ReadDirent repeatedly.
|
||||||
|
// It won't handle assigning the results of lseek to *basep, or handle
|
||||||
|
// the directory being edited underfoot.
|
||||||
|
|
||||||
|
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get path from fd to avoid unavailable call (fdopendir)
|
||||||
|
path, err := fdToPath(fd)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
d, err := Opendir(path)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer Closedir(d)
|
||||||
|
|
||||||
|
var cnt int64
|
||||||
|
for {
|
||||||
|
var entryLE direntLE
|
||||||
|
var entrypLE *direntLE
|
||||||
|
e := readdir_r(d, &entryLE, &entrypLE)
|
||||||
|
if e != nil {
|
||||||
|
return n, e
|
||||||
|
}
|
||||||
|
if entrypLE == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if skip > 0 {
|
||||||
|
skip--
|
||||||
|
cnt++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dirent on zos has a different structure
|
||||||
|
entry, e := direntLeToDirentUnix(&entryLE, d, path)
|
||||||
|
if e != nil {
|
||||||
|
return n, e
|
||||||
|
}
|
||||||
|
|
||||||
|
reclen := int(entry.Reclen)
|
||||||
|
if reclen > len(buf) {
|
||||||
|
// Not enough room. Return for now.
|
||||||
|
// The counter will let us know where we should start up again.
|
||||||
|
// Note: this strategy for suspending in the middle and
|
||||||
|
// restarting is O(n^2) in the length of the directory. Oh well.
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy entry into return buffer.
|
||||||
|
s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
|
||||||
|
copy(buf, s)
|
||||||
|
|
||||||
|
buf = buf[reclen:]
|
||||||
|
n += reclen
|
||||||
|
cnt++
|
||||||
|
}
|
||||||
|
// Set the seek offset of the input fd to record
|
||||||
|
// how many files we've already returned.
|
||||||
|
_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadDirent(fd int, buf []byte) (n int, err error) {
|
||||||
|
var base = (*uintptr)(unsafe.Pointer(new(uint64)))
|
||||||
|
return Getdirentries(fd, buf, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
func direntIno(buf []byte) (uint64, bool) {
|
||||||
|
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
|
||||||
|
}
|
||||||
|
|
||||||
|
func direntReclen(buf []byte) (uint64, bool) {
|
||||||
|
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
|
||||||
|
}
|
||||||
|
|
||||||
|
func direntNamlen(buf []byte) (uint64, bool) {
|
||||||
|
reclen, ok := direntReclen(buf)
|
||||||
|
if !ok {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
|
||||||
|
}
|
||||||
|
13
src/runtime/vendor/golang.org/x/sys/unix/sysvshm_unix.go
generated
vendored
13
src/runtime/vendor/golang.org/x/sys/unix/sysvshm_unix.go
generated
vendored
@ -7,11 +7,7 @@
|
|||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
import (
|
import "unsafe"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"golang.org/x/sys/internal/unsafeheader"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SysvShmAttach attaches the Sysv shared memory segment associated with the
|
// SysvShmAttach attaches the Sysv shared memory segment associated with the
|
||||||
// shared memory identifier id.
|
// shared memory identifier id.
|
||||||
@ -34,12 +30,7 @@ func SysvShmAttach(id int, addr uintptr, flag int) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use unsafe to convert addr into a []byte.
|
// Use unsafe to convert addr into a []byte.
|
||||||
// TODO: convert to unsafe.Slice once we can assume Go 1.17
|
b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), int(info.Segsz))
|
||||||
var b []byte
|
|
||||||
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
|
|
||||||
hdr.Data = unsafe.Pointer(addr)
|
|
||||||
hdr.Cap = int(info.Segsz)
|
|
||||||
hdr.Len = int(info.Segsz)
|
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
95
src/runtime/vendor/golang.org/x/sys/unix/xattr_bsd.go
generated
vendored
95
src/runtime/vendor/golang.org/x/sys/unix/xattr_bsd.go
generated
vendored
@ -160,13 +160,12 @@ func Lremovexattr(link string, attr string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Listxattr(file string, dest []byte) (sz int, err error) {
|
func Listxattr(file string, dest []byte) (sz int, err error) {
|
||||||
d := initxattrdest(dest, 0)
|
|
||||||
destsiz := len(dest)
|
destsiz := len(dest)
|
||||||
|
|
||||||
// FreeBSD won't allow you to list xattrs from multiple namespaces
|
// FreeBSD won't allow you to list xattrs from multiple namespaces
|
||||||
s := 0
|
s, pos := 0, 0
|
||||||
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
||||||
stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
|
stmp, e := ListxattrNS(file, nsid, dest[pos:])
|
||||||
|
|
||||||
/* Errors accessing system attrs are ignored so that
|
/* Errors accessing system attrs are ignored so that
|
||||||
* we can implement the Linux-like behavior of omitting errors that
|
* we can implement the Linux-like behavior of omitting errors that
|
||||||
@ -175,66 +174,102 @@ func Listxattr(file string, dest []byte) (sz int, err error) {
|
|||||||
* Linux will still error if we ask for user attributes on a file that
|
* Linux will still error if we ask for user attributes on a file that
|
||||||
* we don't have read permissions on, so don't ignore those errors
|
* we don't have read permissions on, so don't ignore those errors
|
||||||
*/
|
*/
|
||||||
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
if e != nil {
|
||||||
continue
|
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
||||||
} else if e != nil {
|
continue
|
||||||
|
}
|
||||||
return s, e
|
return s, e
|
||||||
}
|
}
|
||||||
|
|
||||||
s += stmp
|
s += stmp
|
||||||
destsiz -= s
|
pos = s
|
||||||
if destsiz < 0 {
|
if pos > destsiz {
|
||||||
destsiz = 0
|
pos = destsiz
|
||||||
}
|
}
|
||||||
d = initxattrdest(dest, s)
|
}
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListxattrNS(file string, nsid int, dest []byte) (sz int, err error) {
|
||||||
|
d := initxattrdest(dest, 0)
|
||||||
|
destsiz := len(dest)
|
||||||
|
|
||||||
|
s, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
|
||||||
|
if e != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Flistxattr(fd int, dest []byte) (sz int, err error) {
|
func Flistxattr(fd int, dest []byte) (sz int, err error) {
|
||||||
d := initxattrdest(dest, 0)
|
|
||||||
destsiz := len(dest)
|
destsiz := len(dest)
|
||||||
|
|
||||||
s := 0
|
s, pos := 0, 0
|
||||||
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
||||||
stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
|
stmp, e := FlistxattrNS(fd, nsid, dest[pos:])
|
||||||
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
|
||||||
continue
|
if e != nil {
|
||||||
} else if e != nil {
|
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return s, e
|
return s, e
|
||||||
}
|
}
|
||||||
|
|
||||||
s += stmp
|
s += stmp
|
||||||
destsiz -= s
|
pos = s
|
||||||
if destsiz < 0 {
|
if pos > destsiz {
|
||||||
destsiz = 0
|
pos = destsiz
|
||||||
}
|
}
|
||||||
d = initxattrdest(dest, s)
|
}
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func FlistxattrNS(fd int, nsid int, dest []byte) (sz int, err error) {
|
||||||
|
d := initxattrdest(dest, 0)
|
||||||
|
destsiz := len(dest)
|
||||||
|
|
||||||
|
s, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
|
||||||
|
if e != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Llistxattr(link string, dest []byte) (sz int, err error) {
|
func Llistxattr(link string, dest []byte) (sz int, err error) {
|
||||||
d := initxattrdest(dest, 0)
|
|
||||||
destsiz := len(dest)
|
destsiz := len(dest)
|
||||||
|
|
||||||
s := 0
|
s, pos := 0, 0
|
||||||
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
||||||
stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
|
stmp, e := LlistxattrNS(link, nsid, dest[pos:])
|
||||||
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
|
||||||
continue
|
if e != nil {
|
||||||
} else if e != nil {
|
if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return s, e
|
return s, e
|
||||||
}
|
}
|
||||||
|
|
||||||
s += stmp
|
s += stmp
|
||||||
destsiz -= s
|
pos = s
|
||||||
if destsiz < 0 {
|
if pos > destsiz {
|
||||||
destsiz = 0
|
pos = destsiz
|
||||||
}
|
}
|
||||||
d = initxattrdest(dest, s)
|
}
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func LlistxattrNS(link string, nsid int, dest []byte) (sz int, err error) {
|
||||||
|
d := initxattrdest(dest, 0)
|
||||||
|
destsiz := len(dest)
|
||||||
|
|
||||||
|
s, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
|
||||||
|
if e != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
generated
vendored
@ -1,11 +1,11 @@
|
|||||||
// mkerrors.sh -Wall -Werror -static -I/tmp/include -m32
|
// mkerrors.sh -Wall -Werror -static -I/tmp/386/include -m32
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||||
|
|
||||||
//go:build 386 && linux
|
//go:build 386 && linux
|
||||||
// +build 386,linux
|
// +build 386,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m32 _const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/386/include -m32 _const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
generated
vendored
@ -1,11 +1,11 @@
|
|||||||
// mkerrors.sh -Wall -Werror -static -I/tmp/include -m64
|
// mkerrors.sh -Wall -Werror -static -I/tmp/amd64/include -m64
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||||
|
|
||||||
//go:build amd64 && linux
|
//go:build amd64 && linux
|
||||||
// +build amd64,linux
|
// +build amd64,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m64 _const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/amd64/include -m64 _const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
generated
vendored
@ -1,11 +1,11 @@
|
|||||||
// mkerrors.sh -Wall -Werror -static -I/tmp/include
|
// mkerrors.sh -Wall -Werror -static -I/tmp/arm/include
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||||
|
|
||||||
//go:build arm && linux
|
//go:build arm && linux
|
||||||
// +build arm,linux
|
// +build arm,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/arm/include _const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
generated
vendored
@ -1,11 +1,11 @@
|
|||||||
// mkerrors.sh -Wall -Werror -static -I/tmp/include -fsigned-char
|
// mkerrors.sh -Wall -Werror -static -I/tmp/arm64/include -fsigned-char
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||||
|
|
||||||
//go:build arm64 && linux
|
//go:build arm64 && linux
|
||||||
// +build arm64,linux
|
// +build arm64,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char _const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/arm64/include -fsigned-char _const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go
generated
vendored
@ -1,11 +1,11 @@
|
|||||||
// mkerrors.sh -Wall -Werror -static -I/tmp/include
|
// mkerrors.sh -Wall -Werror -static -I/tmp/loong64/include
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||||
|
|
||||||
//go:build loong64 && linux
|
//go:build loong64 && linux
|
||||||
// +build loong64,linux
|
// +build loong64,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/loong64/include _const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
4
src/runtime/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
generated
vendored
4
src/runtime/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
generated
vendored
@ -1,11 +1,11 @@
|
|||||||
// mkerrors.sh -Wall -Werror -static -I/tmp/include
|
// mkerrors.sh -Wall -Werror -static -I/tmp/mips/include
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
// Code generated by the command above; see README.md. DO NOT EDIT.
|
||||||
|
|
||||||
//go:build mips && linux
|
//go:build mips && linux
|
||||||
// +build mips,linux
|
// +build mips,linux
|
||||||
|
|
||||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||||
// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
|
// cgo -godefs -- -Wall -Werror -static -I/tmp/mips/include _const.go
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user