Enable TLS and basic authentication (#730)
authorJulien Pivotto <roidelapluie@inuits.eu>
Wed, 6 Jan 2021 19:34:11 +0000 (20:34 +0100)
committerGitHub <noreply@github.com>
Wed, 6 Jan 2021 19:34:11 +0000 (20:34 +0100)
Signed-off-by: Julien Pivotto <roidelapluie@inuits.eu>
176 files changed:
README.md
go.mod
go.sum
main.go
prober/http.go
vendor/github.com/alecthomas/units/bytes.go
vendor/github.com/alecthomas/units/go.mod
vendor/github.com/alecthomas/units/go.sum [new file with mode: 0644]
vendor/github.com/alecthomas/units/si.go
vendor/github.com/golang/protobuf/proto/buffer.go
vendor/github.com/golang/protobuf/proto/deprecated.go
vendor/github.com/golang/protobuf/proto/extensions.go
vendor/github.com/golang/protobuf/proto/registry.go
vendor/github.com/golang/protobuf/proto/text_encode.go
vendor/github.com/jpillora/backoff/LICENSE [new file with mode: 0644]
vendor/github.com/jpillora/backoff/README.md [new file with mode: 0644]
vendor/github.com/jpillora/backoff/backoff.go [new file with mode: 0644]
vendor/github.com/jpillora/backoff/go.mod [new file with mode: 0644]
vendor/github.com/mwitkow/go-conntrack/.travis.yml
vendor/github.com/mwitkow/go-conntrack/listener_wrapper.go
vendor/github.com/prometheus/client_golang/prometheus/desc.go
vendor/github.com/prometheus/client_golang/prometheus/histogram.go
vendor/github.com/prometheus/client_golang/prometheus/metric.go
vendor/github.com/prometheus/client_golang/prometheus/registry.go
vendor/github.com/prometheus/client_golang/prometheus/summary.go
vendor/github.com/prometheus/client_golang/prometheus/value.go
vendor/github.com/prometheus/client_golang/prometheus/wrap.go
vendor/github.com/prometheus/common/config/config.go
vendor/github.com/prometheus/common/config/http_config.go
vendor/github.com/prometheus/common/expfmt/decode.go
vendor/github.com/prometheus/common/expfmt/text_parse.go
vendor/github.com/prometheus/common/model/fnv.go
vendor/github.com/prometheus/common/model/time.go
vendor/github.com/prometheus/common/version/info.go
vendor/github.com/prometheus/exporter-toolkit/LICENSE [new file with mode: 0644]
vendor/github.com/prometheus/exporter-toolkit/https/README.md [new file with mode: 0644]
vendor/github.com/prometheus/exporter-toolkit/https/kingpinflag/flag.go [new file with mode: 0644]
vendor/github.com/prometheus/exporter-toolkit/https/tls_config.go [new file with mode: 0644]
vendor/github.com/prometheus/exporter-toolkit/https/users.go [new file with mode: 0644]
vendor/github.com/prometheus/exporter-toolkit/https/web-config.yml [new file with mode: 0644]
vendor/github.com/prometheus/procfs/Makefile.common
vendor/github.com/prometheus/procfs/cpuinfo.go
vendor/github.com/prometheus/procfs/cpuinfo_arm.go [new file with mode: 0644]
vendor/github.com/prometheus/procfs/cpuinfo_arm64.go [new file with mode: 0644]
vendor/github.com/prometheus/procfs/cpuinfo_default.go [new file with mode: 0644]
vendor/github.com/prometheus/procfs/cpuinfo_mips.go [new file with mode: 0644]
vendor/github.com/prometheus/procfs/cpuinfo_mips64.go [new file with mode: 0644]
vendor/github.com/prometheus/procfs/cpuinfo_mips64le.go [new file with mode: 0644]
vendor/github.com/prometheus/procfs/cpuinfo_mipsle.go [new file with mode: 0644]
vendor/github.com/prometheus/procfs/cpuinfo_ppc64.go [new file with mode: 0644]
vendor/github.com/prometheus/procfs/cpuinfo_ppc64le.go [new file with mode: 0644]
vendor/github.com/prometheus/procfs/cpuinfo_s390x.go [new file with mode: 0644]
vendor/github.com/prometheus/procfs/fixtures.ttar
vendor/github.com/prometheus/procfs/fscache.go [new file with mode: 0644]
vendor/github.com/prometheus/procfs/internal/util/parse.go
vendor/github.com/prometheus/procfs/kernel_random.go [new file with mode: 0644]
vendor/github.com/prometheus/procfs/mdstat.go
vendor/github.com/prometheus/procfs/mountinfo.go
vendor/github.com/prometheus/procfs/mountstats.go
vendor/github.com/prometheus/procfs/net_conntrackstat.go
vendor/github.com/prometheus/procfs/proc.go
vendor/github.com/prometheus/procfs/proc_cgroup.go [new file with mode: 0644]
vendor/github.com/prometheus/procfs/proc_fdinfo.go
vendor/github.com/prometheus/procfs/proc_maps.go
vendor/github.com/prometheus/procfs/proc_smaps.go [new file with mode: 0644]
vendor/golang.org/x/crypto/bcrypt/base64.go [new file with mode: 0644]
vendor/golang.org/x/crypto/bcrypt/bcrypt.go [new file with mode: 0644]
vendor/golang.org/x/crypto/blowfish/block.go [new file with mode: 0644]
vendor/golang.org/x/crypto/blowfish/cipher.go [new file with mode: 0644]
vendor/golang.org/x/crypto/blowfish/const.go [new file with mode: 0644]
vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go [new file with mode: 0644]
vendor/golang.org/x/sys/unix/mkerrors.sh
vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go
vendor/golang.org/x/sys/unix/syscall_darwin.go
vendor/golang.org/x/sys/unix/syscall_darwin_386.go
vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
vendor/golang.org/x/sys/unix/syscall_darwin_arm.go
vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go
vendor/golang.org/x/sys/unix/syscall_linux.go
vendor/golang.org/x/sys/unix/syscall_linux_386.go
vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
vendor/golang.org/x/sys/unix/syscall_linux_arm.go
vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
vendor/golang.org/x/sys/unix/syscall_unix.go
vendor/golang.org/x/sys/unix/zerrors_linux.go
vendor/golang.org/x/sys/unix/zerrors_linux_386.go
vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_11.go
vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_11.go
vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_11.go
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_11.go
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
vendor/golang.org/x/sys/unix/zsyscall_linux.go
vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go
vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go
vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go
vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go
vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
vendor/golang.org/x/sys/unix/ztypes_linux.go
vendor/golang.org/x/sys/windows/dll_windows.go
vendor/golang.org/x/sys/windows/env_windows.go
vendor/golang.org/x/sys/windows/memory_windows.go
vendor/golang.org/x/sys/windows/security_windows.go
vendor/golang.org/x/sys/windows/syscall_windows.go
vendor/golang.org/x/sys/windows/zsyscall_windows.go
vendor/google.golang.org/protobuf/encoding/prototext/decode.go
vendor/google.golang.org/protobuf/encoding/prototext/encode.go
vendor/google.golang.org/protobuf/internal/descfmt/stringer.go
vendor/google.golang.org/protobuf/internal/fieldnum/descriptor_gen.go
vendor/google.golang.org/protobuf/internal/fieldsort/fieldsort.go
vendor/google.golang.org/protobuf/internal/filedesc/desc.go
vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go
vendor/google.golang.org/protobuf/internal/impl/codec_gen.go
vendor/google.golang.org/protobuf/internal/impl/codec_message.go
vendor/google.golang.org/protobuf/internal/impl/codec_tables.go
vendor/google.golang.org/protobuf/internal/impl/convert.go
vendor/google.golang.org/protobuf/internal/impl/convert_list.go
vendor/google.golang.org/protobuf/internal/impl/convert_map.go
vendor/google.golang.org/protobuf/internal/impl/legacy_export.go
vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go
vendor/google.golang.org/protobuf/internal/impl/message.go
vendor/google.golang.org/protobuf/internal/impl/message_reflect.go
vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go
vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go
vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go
vendor/google.golang.org/protobuf/internal/impl/validate.go
vendor/google.golang.org/protobuf/internal/impl/weak.go
vendor/google.golang.org/protobuf/internal/version/version.go
vendor/google.golang.org/protobuf/proto/checkinit.go
vendor/google.golang.org/protobuf/proto/encode.go
vendor/google.golang.org/protobuf/proto/extension.go
vendor/google.golang.org/protobuf/proto/merge.go
vendor/google.golang.org/protobuf/proto/reset.go
vendor/google.golang.org/protobuf/proto/size.go
vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go
vendor/google.golang.org/protobuf/reflect/protoreflect/type.go
vendor/google.golang.org/protobuf/reflect/protoreflect/value.go
vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go
vendor/gopkg.in/yaml.v2/.travis.yml
vendor/gopkg.in/yaml.v2/apic.go
vendor/gopkg.in/yaml.v2/go.mod
vendor/gopkg.in/yaml.v2/scannerc.go
vendor/gopkg.in/yaml.v2/yaml.go
vendor/gopkg.in/yaml.v2/yamlh.go
vendor/modules.txt

index 9323f81be3b778799a803a56e97068b8e44f01b3..95dee650618c3757182efde5edb0aacc26e78fc6 100644 (file)
--- a/README.md
+++ b/README.md
@@ -31,6 +31,18 @@ will return metrics for a HTTP probe against google.com. The `probe_success`
 metric indicates if the probe succeeded. Adding a `debug=true` parameter
 will return debug information for that probe.
 
+### TLS and basic authentication
+
+The Blackbox Exporter supports TLS and basic authentication. This enables better
+control of the various HTTP endpoints.
+
+To use TLS and/or basic authentication, you need to pass a configuration file
+using the `--web.config.file` parameter. The format of the file is described
+[in the exporter-toolkit repository](https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md).
+
+Note that the TLS and basic authentication settings affect all HTTP endpoints:
+/metrics for scraping, /probe for probing, and the web UI.
+
 ## Building the software
 
 ### Local Build
diff --git a/go.mod b/go.mod
index 77f560c0597fd10c8854268a2f0131acbe378854..80f7afea4599b05f7bca53797bf5b9baac459dd3 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -4,10 +4,11 @@ require (
        github.com/go-kit/kit v0.10.0
        github.com/miekg/dns v1.1.29
        github.com/pkg/errors v0.9.1
-       github.com/prometheus/client_golang v1.6.0
+       github.com/prometheus/client_golang v1.7.1
        github.com/prometheus/client_model v0.2.0
-       github.com/prometheus/common v0.10.0
-       golang.org/x/net v0.0.0-20200602114024-627f9648deb9
+       github.com/prometheus/common v0.15.0
+       github.com/prometheus/exporter-toolkit v0.4.0
+       golang.org/x/net v0.0.0-20200625001655-4c5254603344
        gopkg.in/alecthomas/kingpin.v2 v2.2.6
        gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
 )
diff --git a/go.sum b/go.sum
index 9b1ce8cb4368d00a189fe2c0a308656baf41305d..30ffdcb29da5c1923dfd31297dc64f924fa8af5e 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -12,6 +12,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
+github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
 github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@@ -88,6 +90,8 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
 github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
 github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
 github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -133,15 +137,19 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
 github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
 github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
+github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
@@ -174,6 +182,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
+github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
 github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
 github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
@@ -215,8 +225,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
 github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
 github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
-github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=
-github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
+github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
+github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -227,17 +237,19 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T
 github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
-github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
-github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
 github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
+github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM=
+github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
+github.com/prometheus/exporter-toolkit v0.4.0 h1:O7Bw+ZKEMzW7vD10IuVF70b8EE4JIG7BvHFj9UKz49g=
+github.com/prometheus/exporter-toolkit v0.4.0/go.mod h1:OCkM4805mmisBhLmVFw858QYi3v0wKdY6/UxrT0pZVg=
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
 github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
-github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
-github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
+github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@@ -248,6 +260,7 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@@ -286,6 +299,9 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9 h1:sYNJzB4J8toYPQTM6pAkcmBRgw9SnQKP9oXCHfgy604=
+golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -312,8 +328,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
 golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
-golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -338,11 +354,14 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
-golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
+golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -390,6 +409,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
 google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
 google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
 google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -409,6 +430,9 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
 gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/main.go b/main.go
index 24e5504e044a5f4e5fad65b17a97cc5d3ad53b47..69839bfc51d9a2978f2aaf35a0412967c1cbbeb1 100644 (file)
--- a/main.go
+++ b/main.go
@@ -39,6 +39,8 @@ import (
        "github.com/prometheus/common/promlog"
        "github.com/prometheus/common/promlog/flag"
        "github.com/prometheus/common/version"
+       "github.com/prometheus/exporter-toolkit/https"
+       httpsflag "github.com/prometheus/exporter-toolkit/https/kingpinflag"
        "gopkg.in/alecthomas/kingpin.v2"
        "gopkg.in/yaml.v3"
 
@@ -52,6 +54,7 @@ var (
        }
 
        configFile    = kingpin.Flag("config.file", "Blackbox exporter configuration file.").Default("blackbox.yml").String()
+       httpsConfig   = httpsflag.AddFlags(kingpin.CommandLine)
        listenAddress = kingpin.Flag("web.listen-address", "The address to listen on for HTTP requests.").Default(":9115").String()
        timeoutOffset = kingpin.Flag("timeout-offset", "Offset to subtract from timeout in seconds.").Default("0.5").Float64()
        configCheck   = kingpin.Flag("config.check", "If true validate the config file and then exit.").Default().Bool()
@@ -369,14 +372,14 @@ func run() int {
                w.Write(c)
        })
 
-       srv := http.Server{Addr: *listenAddress}
+       srv := &http.Server{Addr: *listenAddress}
        srvc := make(chan struct{})
        term := make(chan os.Signal, 1)
        signal.Notify(term, os.Interrupt, syscall.SIGTERM)
 
        go func() {
                level.Info(logger).Log("msg", "Listening on address", "address", *listenAddress)
-               if err := srv.ListenAndServe(); err != http.ErrServerClosed {
+               if err := https.Listen(srv, *httpsConfig, logger); err != http.ErrServerClosed {
                        level.Error(logger).Log("msg", "Error starting HTTP server", "err", err)
                        close(srvc)
                }
index 02c2cb1e46dd25d5e82047acdd220b77586d5532..41182d67c2cb3a0c7dee789058e40667f6a362eb 100644 (file)
@@ -329,14 +329,14 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr
                // the hostname of the target.
                httpClientConfig.TLSConfig.ServerName = targetHost
        }
-       client, err := pconfig.NewClientFromConfig(httpClientConfig, "http_probe", true)
+       client, err := pconfig.NewClientFromConfig(httpClientConfig, "http_probe", true, true)
        if err != nil {
                level.Error(logger).Log("msg", "Error generating HTTP client", "err", err)
                return false
        }
 
        httpClientConfig.TLSConfig.ServerName = ""
-       noServerName, err := pconfig.NewRoundTripperFromConfig(httpClientConfig, "http_probe", true)
+       noServerName, err := pconfig.NewRoundTripperFromConfig(httpClientConfig, "http_probe", true, true)
        if err != nil {
                level.Error(logger).Log("msg", "Error generating HTTP client without ServerName", "err", err)
                return false
index eaadeb8005a585971c3bde149a6911ccc09e58cd..61d0ca479abd464a1730fe3ee969f69ca8eb4de9 100644 (file)
@@ -27,6 +27,7 @@ var (
 
 // ParseBase2Bytes supports both iB and B in base-2 multipliers. That is, KB
 // and KiB are both 1024.
+// However "kB", which is the correct SI spelling of 1000 Bytes, is rejected.
 func ParseBase2Bytes(s string) (Base2Bytes, error) {
        n, err := ParseUnit(s, bytesUnitMap)
        if err != nil {
@@ -68,12 +69,13 @@ func ParseMetricBytes(s string) (MetricBytes, error) {
        return MetricBytes(n), err
 }
 
+// TODO: represents 1000B as uppercase "KB", while SI standard requires "kB".
 func (m MetricBytes) String() string {
        return ToString(int64(m), 1000, "B", "B")
 }
 
 // ParseStrictBytes supports both iB and B suffixes for base 2 and metric,
-// respectively. That is, KiB represents 1024 and KB represents 1000.
+// respectively. That is, KiB represents 1024 and kB, KB represent 1000.
 func ParseStrictBytes(s string) (int64, error) {
        n, err := ParseUnit(s, bytesUnitMap)
        if err != nil {
index f5721732748c45de91469198817029c45c432380..c7fb91f2b27d804ed5afa45978d33a4d532e5651 100644 (file)
@@ -1 +1,3 @@
 module github.com/alecthomas/units
+
+require github.com/stretchr/testify v1.4.0
diff --git a/vendor/github.com/alecthomas/units/go.sum b/vendor/github.com/alecthomas/units/go.sum
new file mode 100644 (file)
index 0000000..8fdee58
--- /dev/null
@@ -0,0 +1,11 @@
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
index 8234a9d52cb3bde880c868b1358b4886de0dcdd4..99b2fa4fcb02ce845d853d10696b54f3c34d60fe 100644 (file)
@@ -14,13 +14,37 @@ const (
 )
 
 func MakeUnitMap(suffix, shortSuffix string, scale int64) map[string]float64 {
-       return map[string]float64{
-               shortSuffix:  1,
-               "K" + suffix: float64(scale),
+       res := map[string]float64{
+               shortSuffix: 1,
+               // see below for "k" / "K"
                "M" + suffix: float64(scale * scale),
                "G" + suffix: float64(scale * scale * scale),
                "T" + suffix: float64(scale * scale * scale * scale),
                "P" + suffix: float64(scale * scale * scale * scale * scale),
                "E" + suffix: float64(scale * scale * scale * scale * scale * scale),
        }
+
+       // Standard SI prefixes use lowercase "k" for kilo = 1000.
+       // For compatibility, and to be fool-proof, we accept both "k" and "K" in metric mode.
+       //
+       // However, official binary prefixes are always capitalized - "KiB" -
+       // and we specifically never parse "kB" as 1024B because:
+       //
+       // (1) people pedantic enough to use lowercase according to SI unlikely to abuse "k" to mean 1024 :-)
+       //
+       // (2) Use of capital K for 1024 was an informal tradition predating IEC prefixes:
+       //     "The binary meaning of the kilobyte for 1024 bytes typically uses the symbol KB, with an
+       //     uppercase letter K."
+       //     -- https://en.wikipedia.org/wiki/Kilobyte#Base_2_(1024_bytes)
+       //     "Capitalization of the letter K became the de facto standard for binary notation, although this
+       //     could not be extended to higher powers, and use of the lowercase k did persist.[13][14][15]"
+       //     -- https://en.wikipedia.org/wiki/Binary_prefix#History
+       //     See also the extensive https://en.wikipedia.org/wiki/Timeline_of_binary_prefixes.
+       if scale == 1024 {
+               res["K"+suffix] = float64(scale)
+       } else {
+               res["k"+suffix] = float64(scale)
+               res["K"+suffix] = float64(scale)
+       }
+       return res
 }
index 62df7e3b8b2bd065702a38b18d7ba8edbff45951..e810e6fea129d47402785bf2850cc8505d51e4c9 100644 (file)
@@ -33,8 +33,8 @@ func SizeVarint(v uint64) int {
        return protowire.SizeVarint(v)
 }
 
-// DecodeVarint parses a varint encoded integer from b, returning the
-// integer value and the length of the varint.
+// DecodeVarint parses a varint encoded integer from b,
+// returning the integer value and the length of the varint.
 // It returns (0, 0) if there is a parse error.
 func DecodeVarint(b []byte) (uint64, int) {
        v, n := protowire.ConsumeVarint(b)
@@ -112,9 +112,9 @@ func (b *Buffer) Marshal(m Message) error {
        return err
 }
 
-// Unmarshal parses the wire-format message in the buffer and places the decoded results in m.
-//
-// Unlike proto.Unmarshal, this does not reset the message before starting to unmarshal.
+// Unmarshal parses the wire-format message in the buffer and
+// places the decoded results in m.
+// It does not reset m before unmarshaling.
 func (b *Buffer) Unmarshal(m Message) error {
        err := UnmarshalMerge(b.Unread(), m)
        b.idx = len(b.buf)
@@ -260,7 +260,7 @@ func (b *Buffer) DecodeStringBytes() (string, error) {
 }
 
 // DecodeMessage consumes a length-prefixed message from the buffer.
-// It does not reset m.
+// It does not reset m before unmarshaling.
 func (b *Buffer) DecodeMessage(m Message) error {
        v, err := b.DecodeRawBytes(false)
        if err != nil {
@@ -272,7 +272,7 @@ func (b *Buffer) DecodeMessage(m Message) error {
 // DecodeGroup consumes a message group from the buffer.
 // It assumes that the start group marker has already been consumed and
 // consumes all bytes until (and including the end group marker).
-// It does not reset m.
+// It does not reset m before unmarshaling.
 func (b *Buffer) DecodeGroup(m Message) error {
        v, n, err := consumeGroup(b.buf[b.idx:])
        if err != nil {
index a205482a32328d3029ec51b3572f7d7f188b11ac..e8db57e097a1a92dd5998e0724ee4ea40910c168 100644 (file)
@@ -9,6 +9,8 @@ import (
        "errors"
        "fmt"
        "strconv"
+
+       protoV2 "google.golang.org/protobuf/proto"
 )
 
 var (
@@ -82,11 +84,30 @@ func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32,
        return val, nil
 }
 
-// Deprecated: Do not use.
+// Deprecated: Do not use; this type existed for intenal-use only.
 type InternalMessageInfo struct{}
 
-func (*InternalMessageInfo) DiscardUnknown(Message)                        { panic("not implemented") }
-func (*InternalMessageInfo) Marshal([]byte, Message, bool) ([]byte, error) { panic("not implemented") }
-func (*InternalMessageInfo) Merge(Message, Message)                        { panic("not implemented") }
-func (*InternalMessageInfo) Size(Message) int                              { panic("not implemented") }
-func (*InternalMessageInfo) Unmarshal(Message, []byte) error               { panic("not implemented") }
+// Deprecated: Do not use; this method existed for intenal-use only.
+func (*InternalMessageInfo) DiscardUnknown(m Message) {
+       DiscardUnknown(m)
+}
+
+// Deprecated: Do not use; this method existed for intenal-use only.
+func (*InternalMessageInfo) Marshal(b []byte, m Message, deterministic bool) ([]byte, error) {
+       return protoV2.MarshalOptions{Deterministic: deterministic}.MarshalAppend(b, MessageV2(m))
+}
+
+// Deprecated: Do not use; this method existed for intenal-use only.
+func (*InternalMessageInfo) Merge(dst, src Message) {
+       protoV2.Merge(MessageV2(dst), MessageV2(src))
+}
+
+// Deprecated: Do not use; this method existed for intenal-use only.
+func (*InternalMessageInfo) Size(m Message) int {
+       return protoV2.Size(MessageV2(m))
+}
+
+// Deprecated: Do not use; this method existed for intenal-use only.
+func (*InternalMessageInfo) Unmarshal(m Message, b []byte) error {
+       return protoV2.UnmarshalOptions{Merge: true}.Unmarshal(b, MessageV2(m))
+}
index 5ed131c57d9f75227a2d3ef8bee650c7cc5edce6..42fc120c972b8399411cf9e5e3bc73644d166525 100644 (file)
@@ -68,7 +68,7 @@ func HasExtension(m Message, xt *ExtensionDesc) (has bool) {
        return has
 }
 
-// ClearExtension removes the the exntesion field from m
+// ClearExtension removes the extension field from m
 // either as an explicitly populated field or as an unknown field.
 func ClearExtension(m Message, xt *ExtensionDesc) {
        mr := MessageReflect(m)
@@ -108,7 +108,7 @@ func ClearAllExtensions(m Message) {
        clearUnknown(mr, mr.Descriptor().ExtensionRanges())
 }
 
-// GetExtension retrieves a proto2 extended field from pb.
+// GetExtension retrieves a proto2 extended field from m.
 //
 // If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
 // then GetExtension parses the encoded field and returns a Go value of the specified type.
index abab110a0651cc257f5af050d1b297844f001f40..1e7ff64205775dd576528bcddb4140f648627635 100644 (file)
@@ -29,7 +29,7 @@ var fileCache sync.Map // map[filePath]fileDescGZIP
 // RegisterFile is called from generated code to register the compressed
 // FileDescriptorProto with the file path for a proto source file.
 //
-// Deprecated: Use protoregistry.GlobalFiles.Register instead.
+// Deprecated: Use protoregistry.GlobalFiles.RegisterFile instead.
 func RegisterFile(s filePath, d fileDescGZIP) {
        // Decompress the descriptor.
        zr, err := gzip.NewReader(bytes.NewReader(d))
@@ -53,7 +53,7 @@ func RegisterFile(s filePath, d fileDescGZIP) {
 // FileDescriptor returns the compressed FileDescriptorProto given the file path
 // for a proto source file. It returns nil if not found.
 //
-// Deprecated: Use protoregistry.GlobalFiles.RangeFilesByPath instead.
+// Deprecated: Use protoregistry.GlobalFiles.FindFileByPath instead.
 func FileDescriptor(s filePath) fileDescGZIP {
        if v, ok := fileCache.Load(s); ok {
                return v.(fileDescGZIP)
@@ -98,7 +98,7 @@ var numFilesCache sync.Map // map[protoreflect.FullName]int
 // RegisterEnum is called from the generated code to register the mapping of
 // enum value names to enum numbers for the enum identified by s.
 //
-// Deprecated: Use protoregistry.GlobalTypes.Register instead.
+// Deprecated: Use protoregistry.GlobalTypes.RegisterEnum instead.
 func RegisterEnum(s enumName, _ enumsByNumber, m enumsByName) {
        if _, ok := enumCache.Load(s); ok {
                panic("proto: duplicate enum registered: " + s)
@@ -181,7 +181,7 @@ var messageTypeCache sync.Map // map[messageName]reflect.Type
 // RegisterType is called from generated code to register the message Go type
 // for a message of the given name.
 //
-// Deprecated: Use protoregistry.GlobalTypes.Register instead.
+// Deprecated: Use protoregistry.GlobalTypes.RegisterMessage instead.
 func RegisterType(m Message, s messageName) {
        mt := protoimpl.X.LegacyMessageTypeOf(m, protoreflect.FullName(s))
        if err := protoregistry.GlobalTypes.RegisterMessage(mt); err != nil {
@@ -280,7 +280,7 @@ func MessageName(m Message) messageName {
 // RegisterExtension is called from the generated code to register
 // the extension descriptor.
 //
-// Deprecated: Use protoregistry.GlobalTypes.Register instead.
+// Deprecated: Use protoregistry.GlobalTypes.RegisterExtension instead.
 func RegisterExtension(d *ExtensionDesc) {
        if err := protoregistry.GlobalTypes.RegisterExtension(d); err != nil {
                panic(err)
index 7ac02e68f62860a464dec4b940d03cb5481e843e..a31134eeb3b7dc49285ea1215f6e643d72eccb5d 100644 (file)
@@ -94,16 +94,16 @@ var (
 )
 
 // MarshalText writes the proto text format of m to w.
-func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }
+func MarshalText(w io.Writer, m Message) error { return defaultTextMarshaler.Marshal(w, m) }
 
 // MarshalTextString returns a proto text formatted string of m.
-func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }
+func MarshalTextString(m Message) string { return defaultTextMarshaler.Text(m) }
 
 // CompactText writes the compact proto text format of m to w.
-func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }
+func CompactText(w io.Writer, m Message) error { return compactTextMarshaler.Marshal(w, m) }
 
 // CompactTextString returns a compact proto text formatted string of m.
-func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }
+func CompactTextString(m Message) string { return compactTextMarshaler.Text(m) }
 
 var (
        newline         = []byte("\n")
diff --git a/vendor/github.com/jpillora/backoff/LICENSE b/vendor/github.com/jpillora/backoff/LICENSE
new file mode 100644 (file)
index 0000000..1cc7080
--- /dev/null
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2017 Jaime Pillora
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/jpillora/backoff/README.md b/vendor/github.com/jpillora/backoff/README.md
new file mode 100644 (file)
index 0000000..ee4d623
--- /dev/null
@@ -0,0 +1,119 @@
+# Backoff
+
+A simple exponential backoff counter in Go (Golang)
+
+[![GoDoc](https://godoc.org/github.com/jpillora/backoff?status.svg)](https://godoc.org/github.com/jpillora/backoff) [![Circle CI](https://circleci.com/gh/jpillora/backoff.svg?style=shield)](https://circleci.com/gh/jpillora/backoff)
+
+### Install
+
+```
+$ go get -v github.com/jpillora/backoff
+```
+
+### Usage
+
+Backoff is a `time.Duration` counter. It starts at `Min`. After every call to `Duration()` it is  multiplied by `Factor`. It is capped at `Max`. It returns to `Min` on every call to `Reset()`. `Jitter` adds randomness ([see below](#example-using-jitter)). Used in conjunction with the `time` package.
+
+---
+
+#### Simple example
+
+``` go
+
+b := &backoff.Backoff{
+       //These are the defaults
+       Min:    100 * time.Millisecond,
+       Max:    10 * time.Second,
+       Factor: 2,
+       Jitter: false,
+}
+
+fmt.Printf("%s\n", b.Duration())
+fmt.Printf("%s\n", b.Duration())
+fmt.Printf("%s\n", b.Duration())
+
+fmt.Printf("Reset!\n")
+b.Reset()
+
+fmt.Printf("%s\n", b.Duration())
+```
+
+```
+100ms
+200ms
+400ms
+Reset!
+100ms
+```
+
+---
+
+#### Example using `net` package
+
+``` go
+b := &backoff.Backoff{
+    Max:    5 * time.Minute,
+}
+
+for {
+       conn, err := net.Dial("tcp", "example.com:5309")
+       if err != nil {
+               d := b.Duration()
+               fmt.Printf("%s, reconnecting in %s", err, d)
+               time.Sleep(d)
+               continue
+       }
+       //connected
+       b.Reset()
+       conn.Write([]byte("hello world!"))
+       // ... Read ... Write ... etc
+       conn.Close()
+       //disconnected
+}
+
+```
+
+---
+
+#### Example using `Jitter`
+
+Enabling `Jitter` adds some randomization to the backoff durations. [See Amazon's writeup of performance gains using jitter](http://www.awsarchitectureblog.com/2015/03/backoff.html). Seeding is not necessary but doing so gives repeatable results.
+
+```go
+import "math/rand"
+
+b := &backoff.Backoff{
+       Jitter: true,
+}
+
+rand.Seed(42)
+
+fmt.Printf("%s\n", b.Duration())
+fmt.Printf("%s\n", b.Duration())
+fmt.Printf("%s\n", b.Duration())
+
+fmt.Printf("Reset!\n")
+b.Reset()
+
+fmt.Printf("%s\n", b.Duration())
+fmt.Printf("%s\n", b.Duration())
+fmt.Printf("%s\n", b.Duration())
+```
+
+```
+100ms
+106.600049ms
+281.228155ms
+Reset!
+100ms
+104.381845ms
+214.957989ms
+```
+
+#### Documentation
+
+https://godoc.org/github.com/jpillora/backoff
+
+#### Credits
+
+Forked from [some JavaScript](https://github.com/segmentio/backo) written by [@tj](https://github.com/tj)
diff --git a/vendor/github.com/jpillora/backoff/backoff.go b/vendor/github.com/jpillora/backoff/backoff.go
new file mode 100644 (file)
index 0000000..d113e68
--- /dev/null
@@ -0,0 +1,100 @@
+// Package backoff provides an exponential-backoff implementation.
+package backoff
+
+import (
+       "math"
+       "math/rand"
+       "sync/atomic"
+       "time"
+)
+
+// Backoff is a time.Duration counter, starting at Min. After every call to
+// the Duration method the current timing is multiplied by Factor, but it
+// never exceeds Max.
+//
+// Backoff is not generally concurrent-safe, but the ForAttempt method can
+// be used concurrently.
+type Backoff struct {
+       attempt uint64
+       // Factor is the multiplying factor for each increment step
+       Factor float64
+       // Jitter eases contention by randomizing backoff steps
+       Jitter bool
+       // Min and Max are the minimum and maximum values of the counter
+       Min, Max time.Duration
+}
+
+// Duration returns the duration for the current attempt before incrementing
+// the attempt counter. See ForAttempt.
+func (b *Backoff) Duration() time.Duration {
+       d := b.ForAttempt(float64(atomic.AddUint64(&b.attempt, 1) - 1))
+       return d
+}
+
+const maxInt64 = float64(math.MaxInt64 - 512)
+
+// ForAttempt returns the duration for a specific attempt. This is useful if
+// you have a large number of independent Backoffs, but don't want use
+// unnecessary memory storing the Backoff parameters per Backoff. The first
+// attempt should be 0.
+//
+// ForAttempt is concurrent-safe.
+func (b *Backoff) ForAttempt(attempt float64) time.Duration {
+       // Zero-values are nonsensical, so we use
+       // them to apply defaults
+       min := b.Min
+       if min <= 0 {
+               min = 100 * time.Millisecond
+       }
+       max := b.Max
+       if max <= 0 {
+               max = 10 * time.Second
+       }
+       if min >= max {
+               // short-circuit
+               return max
+       }
+       factor := b.Factor
+       if factor <= 0 {
+               factor = 2
+       }
+       //calculate this duration
+       minf := float64(min)
+       durf := minf * math.Pow(factor, attempt)
+       if b.Jitter {
+               durf = rand.Float64()*(durf-minf) + minf
+       }
+       //ensure float64 wont overflow int64
+       if durf > maxInt64 {
+               return max
+       }
+       dur := time.Duration(durf)
+       //keep within bounds
+       if dur < min {
+               return min
+       }
+       if dur > max {
+               return max
+       }
+       return dur
+}
+
+// Reset restarts the current attempt counter at zero.
+func (b *Backoff) Reset() {
+       atomic.StoreUint64(&b.attempt, 0)
+}
+
+// Attempt returns the current attempt counter value.
+func (b *Backoff) Attempt() float64 {
+       return float64(atomic.LoadUint64(&b.attempt))
+}
+
+// Copy returns a backoff with equals constraints as the original
+func (b *Backoff) Copy() *Backoff {
+       return &Backoff{
+               Factor: b.Factor,
+               Jitter: b.Jitter,
+               Min:    b.Min,
+               Max:    b.Max,
+       }
+}
diff --git a/vendor/github.com/jpillora/backoff/go.mod b/vendor/github.com/jpillora/backoff/go.mod
new file mode 100644 (file)
index 0000000..7c41bc6
--- /dev/null
@@ -0,0 +1,3 @@
+module github.com/jpillora/backoff
+
+go 1.13
index db676f65711039d00323b89f6600c742c66aba27..a9654fa05a3af38be6e7d95571b1c52ca75a7cc6 100644 (file)
@@ -1,13 +1,17 @@
 sudo: false
 language: go
 go:
-  - 1.7
+- "1.8"
+- "1.9"
+- "1.10"
+- "1.11"
+- "1.12"
 
 install:
-  - go get github.com/stretchr/testify
-  - go get github.com/prometheus/client_golang/prometheus
-  - go get golang.org/x/net/context
-  - go get golang.org/x/net/trace
+- go get github.com/stretchr/testify
+- go get github.com/prometheus/client_golang/prometheus
+- go get golang.org/x/net/context
+- go get golang.org/x/net/trace
 
 script:
- - go test -v ./...
+- go test -v ./...
index 6754c00d9392f7a2c19445ba106889696b004416..702fe25577a6407b60314771eef4a4d0b8aaf50d 100644 (file)
@@ -6,11 +6,11 @@ package conntrack
 import (
        "fmt"
        "net"
-
        "sync"
+       "time"
 
+       "github.com/jpillora/backoff"
        "golang.org/x/net/trace"
-       "time"
 )
 
 const (
@@ -22,6 +22,7 @@ type listenerOpts struct {
        monitoring   bool
        tracing      bool
        tcpKeepAlive time.Duration
+       retryBackoff *backoff.Backoff
 }
 
 type listenerOpt func(*listenerOpts)
@@ -47,6 +48,14 @@ func TrackWithTracing() listenerOpt {
        }
 }
 
+// TrackWithRetries enables retrying of temporary Accept() errors, with the given backoff between attempts.
+// Concurrent accept calls that receive temporary errors have independent backoff scaling.
+func TrackWithRetries(b backoff.Backoff) listenerOpt {
+       return func(opts *listenerOpts) {
+               opts.retryBackoff = &b
+       }
+}
+
 // TrackWithTcpKeepAlive makes sure that any `net.TCPConn` that get accepted have a keep-alive.
 // This is useful for HTTP servers in order for, for example laptops, to not use up resources on the
 // server while they don't utilise their connection.
@@ -83,7 +92,20 @@ func NewListener(inner net.Listener, optFuncs ...listenerOpt) net.Listener {
 
 func (ct *connTrackListener) Accept() (net.Conn, error) {
        // TODO(mwitkow): Add monitoring of failed accept.
-       conn, err := ct.Listener.Accept()
+       var (
+               conn net.Conn
+               err  error
+       )
+       for attempt := 0; ; attempt++ {
+               conn, err = ct.Listener.Accept()
+               if err == nil || ct.opts.retryBackoff == nil {
+                       break
+               }
+               if t, ok := err.(interface{ Temporary() bool }); !ok || !t.Temporary() {
+                       break
+               }
+               time.Sleep(ct.opts.retryBackoff.ForAttempt(float64(attempt)))
+       }
        if err != nil {
                return nil, err
        }
@@ -102,7 +124,6 @@ type serverConnTracker struct {
 }
 
 func newServerConnTracker(inner net.Conn, opts *listenerOpts) net.Conn {
-
        tracker := &serverConnTracker{
                Conn: inner,
                opts: opts,
index e3232d79f44b998e8de4852914e7d9211f284254..2f19f5e1e7eafc1df8bd6b649ff0dc15e28eb4c1 100644 (file)
@@ -20,6 +20,7 @@ import (
        "strings"
 
        "github.com/cespare/xxhash/v2"
+       //lint:ignore SA1019 Need to keep deprecated package for compatibility.
        "github.com/golang/protobuf/proto"
        "github.com/prometheus/common/model"
 
index 4271f438aeaaf2441c389121db8c96a0201e02a6..d4ea301a33ce1bbe39bc1d4e852cb6d91273b5dd 100644 (file)
@@ -22,6 +22,7 @@ import (
        "sync/atomic"
        "time"
 
+       //lint:ignore SA1019 Need to keep deprecated package for compatibility.
        "github.com/golang/protobuf/proto"
 
        dto "github.com/prometheus/client_model/go"
@@ -606,7 +607,7 @@ func NewConstHistogram(
 }
 
 // MustNewConstHistogram is a version of NewConstHistogram that panics where
-// NewConstMetric would have returned an error.
+// NewConstHistogram would have returned an error.
 func MustNewConstHistogram(
        desc *Desc,
        count uint64,
index 0df1eff8814fbf04ede8e766c73fe16658f2260a..35bd8bde34c7570c1b636fd155f8cffdd8f27abe 100644 (file)
@@ -17,6 +17,7 @@ import (
        "strings"
        "time"
 
+       //lint:ignore SA1019 Need to keep deprecated package for compatibility.
        "github.com/golang/protobuf/proto"
        "github.com/prometheus/common/model"
 
index c05d6ee1b3853ac7cf6e905aff9d3231cc930478..ba94405af4cafc663740c5bd86406b1c7ec40b97 100644 (file)
@@ -26,6 +26,7 @@ import (
        "unicode/utf8"
 
        "github.com/cespare/xxhash/v2"
+       //lint:ignore SA1019 Need to keep deprecated package for compatibility.
        "github.com/golang/protobuf/proto"
        "github.com/prometheus/common/expfmt"
 
index ae42e761a19a2a58f0d2f7f04e49dd8cb518851d..f3c1440d1c65b58a4a9bd0790b34e4b654927c7b 100644 (file)
@@ -23,6 +23,7 @@ import (
        "time"
 
        "github.com/beorn7/perks/quantile"
+       //lint:ignore SA1019 Need to keep deprecated package for compatibility.
        "github.com/golang/protobuf/proto"
 
        dto "github.com/prometheus/client_model/go"
index 2be470ce15275acadda150b02a456b6b75f6217d..6206928cc67c221d3bd6a98bc06832a84368e5f2 100644 (file)
@@ -19,6 +19,7 @@ import (
        "time"
        "unicode/utf8"
 
+       //lint:ignore SA1019 Need to keep deprecated package for compatibility.
        "github.com/golang/protobuf/proto"
        "github.com/golang/protobuf/ptypes"
 
index e303eef6d33be1669754875fbfb65928308e4e61..438aa5e9247d9cac7fa64d2c77b63d8ca0655ed6 100644 (file)
@@ -17,6 +17,7 @@ import (
        "fmt"
        "sort"
 
+       //lint:ignore SA1019 Need to keep deprecated package for compatibility.
        "github.com/golang/protobuf/proto"
 
        dto "github.com/prometheus/client_model/go"
@@ -27,7 +28,8 @@ import (
 // registered with the wrapped Registerer in a modified way. The modified
 // Collector adds the provided Labels to all Metrics it collects (as
 // ConstLabels). The Metrics collected by the unmodified Collector must not
-// duplicate any of those labels.
+// duplicate any of those labels. Wrapping a nil value is valid, resulting
+// in a no-op Registerer.
 //
 // WrapRegistererWith provides a way to add fixed labels to a subset of
 // Collectors. It should not be used to add fixed labels to all metrics exposed.
@@ -50,6 +52,7 @@ func WrapRegistererWith(labels Labels, reg Registerer) Registerer {
 // Registerer. Collectors registered with the returned Registerer will be
 // registered with the wrapped Registerer in a modified way. The modified
 // Collector adds the provided prefix to the name of all Metrics it collects.
+// Wrapping a nil value is valid, resulting in a no-op Registerer.
 //
 // WrapRegistererWithPrefix is useful to have one place to prefix all metrics of
 // a sub-system. To make this work, register metrics of the sub-system with the
@@ -80,6 +83,9 @@ type wrappingRegisterer struct {
 }
 
 func (r *wrappingRegisterer) Register(c Collector) error {
+       if r.wrappedRegisterer == nil {
+               return nil
+       }
        return r.wrappedRegisterer.Register(&wrappingCollector{
                wrappedCollector: c,
                prefix:           r.prefix,
@@ -88,6 +94,9 @@ func (r *wrappingRegisterer) Register(c Collector) error {
 }
 
 func (r *wrappingRegisterer) MustRegister(cs ...Collector) {
+       if r.wrappedRegisterer == nil {
+               return
+       }
        for _, c := range cs {
                if err := r.Register(c); err != nil {
                        panic(err)
@@ -96,6 +105,9 @@ func (r *wrappingRegisterer) MustRegister(cs ...Collector) {
 }
 
 func (r *wrappingRegisterer) Unregister(c Collector) bool {
+       if r.wrappedRegisterer == nil {
+               return false
+       }
        return r.wrappedRegisterer.Unregister(&wrappingCollector{
                wrappedCollector: c,
                prefix:           r.prefix,
index 30719d838625e24a4a4ed385425cfded9b890025..d8a7351f994f923d697f69d786cab4b9ed0f95ba 100644 (file)
@@ -16,6 +16,8 @@
 
 package config
 
+import "path/filepath"
+
 // Secret special type for storing secrets.
 type Secret string
 
@@ -32,3 +34,20 @@ func (s *Secret) UnmarshalYAML(unmarshal func(interface{}) error) error {
        type plain Secret
        return unmarshal((*plain)(s))
 }
+
+// DirectorySetter is a config type that contains file paths that may
+// be relative to the file containing the config.
+type DirectorySetter interface {
+       // SetDirectory joins any relative file paths with dir.
+       // Any paths that are empty or absolute remain unchanged.
+       SetDirectory(dir string)
+}
+
+// JoinDir joins dir and path if path is relative.
+// If path is empty or absolute, it is returned unchanged.
+func JoinDir(dir, path string) string {
+       if path == "" || filepath.IsAbs(path) {
+               return path
+       }
+       return filepath.Join(dir, path)
+}
index 9b1fad93fa610a054bd143dc45b5c2cd223513dc..4dd8875855ccf516036a79f03919be9facca7d2b 100644 (file)
@@ -44,6 +44,14 @@ type BasicAuth struct {
        PasswordFile string `yaml:"password_file,omitempty"`
 }
 
+// SetDirectory joins any relative file paths with dir.
+func (a *BasicAuth) SetDirectory(dir string) {
+       if a == nil {
+               return
+       }
+       a.PasswordFile = JoinDir(dir, a.PasswordFile)
+}
+
 // URL is a custom URL type that allows validation at configuration load time.
 type URL struct {
        *url.URL
@@ -86,6 +94,16 @@ type HTTPClientConfig struct {
        TLSConfig TLSConfig `yaml:"tls_config,omitempty"`
 }
 
+// SetDirectory joins any relative file paths with dir.
+func (c *HTTPClientConfig) SetDirectory(dir string) {
+       if c == nil {
+               return
+       }
+       c.TLSConfig.SetDirectory(dir)
+       c.BasicAuth.SetDirectory(dir)
+       c.BearerTokenFile = JoinDir(dir, c.BearerTokenFile)
+}
+
 // Validate validates the HTTPClientConfig to check only one of BearerToken,
 // BasicAuth and BearerTokenFile is configured.
 func (c *HTTPClientConfig) Validate() error {
@@ -123,8 +141,8 @@ func newClient(rt http.RoundTripper) *http.Client {
 
 // NewClientFromConfig returns a new HTTP client configured for the
 // given config.HTTPClientConfig. The name is used as go-conntrack metric label.
-func NewClientFromConfig(cfg HTTPClientConfig, name string, disableKeepAlives bool) (*http.Client, error) {
-       rt, err := NewRoundTripperFromConfig(cfg, name, disableKeepAlives)
+func NewClientFromConfig(cfg HTTPClientConfig, name string, disableKeepAlives, enableHTTP2 bool) (*http.Client, error) {
+       rt, err := NewRoundTripperFromConfig(cfg, name, disableKeepAlives, enableHTTP2)
        if err != nil {
                return nil, err
        }
@@ -133,7 +151,7 @@ func NewClientFromConfig(cfg HTTPClientConfig, name string, disableKeepAlives bo
 
 // NewRoundTripperFromConfig returns a new HTTP RoundTripper configured for the
 // given config.HTTPClientConfig. The name is used as go-conntrack metric label.
-func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, disableKeepAlives bool) (http.RoundTripper, error) {
+func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, disableKeepAlives, enableHTTP2 bool) (http.RoundTripper, error) {
        newRT := func(tlsConfig *tls.Config) (http.RoundTripper, error) {
                // The only timeout we care about is the configured scrape timeout.
                // It is applied on request. So we leave out any timings here.
@@ -154,10 +172,18 @@ func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, disableKeepAli
                                conntrack.DialWithName(name),
                        ),
                }
-               // TODO: use ForceAttemptHTTP2 when we move to Go 1.13+.
-               err := http2.ConfigureTransport(rt.(*http.Transport))
-               if err != nil {
-                       return nil, err
+               if enableHTTP2 {
+                       // HTTP/2 support is golang has many problematic cornercases where
+                       // dead connections would be kept and used in connection pools.
+                       // https://github.com/golang/go/issues/32388
+                       // https://github.com/golang/go/issues/39337
+                       // https://github.com/golang/go/issues/39750
+                       // TODO: Re-Enable HTTP/2 once upstream issue is fixed.
+                       // TODO: use ForceAttemptHTTP2 when we move to Go 1.13+.
+                       err := http2.ConfigureTransport(rt.(*http.Transport))
+                       if err != nil {
+                               return nil, err
+                       }
                }
 
                // If a bearer token is provided, create a round tripper that will set the
@@ -344,6 +370,16 @@ type TLSConfig struct {
        InsecureSkipVerify bool `yaml:"insecure_skip_verify"`
 }
 
+// SetDirectory joins any relative file paths with dir.
+func (c *TLSConfig) SetDirectory(dir string) {
+       if c == nil {
+               return
+       }
+       c.CAFile = JoinDir(dir, c.CAFile)
+       c.CertFile = JoinDir(dir, c.CertFile)
+       c.KeyFile = JoinDir(dir, c.KeyFile)
+}
+
 // UnmarshalYAML implements the yaml.Unmarshaler interface.
 func (c *TLSConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
        type plain TLSConfig
index c092723e84a4019c022b1f6bb84e9af303eb1638..7657f841d632b96dd4e206e7487235188d94160b 100644 (file)
@@ -164,7 +164,7 @@ func (sd *SampleDecoder) Decode(s *model.Vector) error {
 }
 
 // ExtractSamples builds a slice of samples from the provided metric
-// families. If an error occurrs during sample extraction, it continues to
+// families. If an error occurs during sample extraction, it continues to
 // extract from the remaining metric families. The returned error is the last
 // error that has occurred.
 func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) (model.Vector, error) {
index 342e5940d0f7d2270bb2112e9c9c9e859383aebe..b6079b31eeb5a85ab19ea00d0a4163081752165d 100644 (file)
@@ -299,6 +299,17 @@ func (p *TextParser) startLabelName() stateFn {
                p.parseError(fmt.Sprintf("expected '=' after label name, found %q", p.currentByte))
                return nil
        }
+       // Check for duplicate label names.
+       labels := make(map[string]struct{})
+       for _, l := range p.currentMetric.Label {
+               lName := l.GetName()
+               if _, exists := labels[lName]; !exists {
+                       labels[lName] = struct{}{}
+               } else {
+                       p.parseError(fmt.Sprintf("duplicate label names for metric %q", p.currentMF.GetName()))
+                       return nil
+               }
+       }
        return p.startLabelValue
 }
 
index 038fc1c9003caa6b5412202fac52e8e5e5ec8809..367afecd30e6503bfc198d5caf4f267fe246dfd7 100644 (file)
@@ -20,7 +20,7 @@ const (
        prime64  = 1099511628211
 )
 
-// hashNew initializies a new fnv64a hash value.
+// hashNew initializes a new fnv64a hash value.
 func hashNew() uint64 {
        return offset64
 }
index 490a0240c1014b1dfc2b7b0409c05621a1918227..c40e6403ca8032f1d44029a08d8ef67180a112e0 100644 (file)
@@ -181,77 +181,77 @@ func (d *Duration) Type() string {
        return "duration"
 }
 
-var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$")
+var durationRE = regexp.MustCompile("^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$")
 
 // ParseDuration parses a string into a time.Duration, assuming that a year
 // always has 365d, a week always has 7d, and a day always has 24h.
 func ParseDuration(durationStr string) (Duration, error) {
-       // Allow 0 without a unit.
-       if durationStr == "0" {
+       switch durationStr {
+       case "0":
+               // Allow 0 without a unit.
                return 0, nil
+       case "":
+               return 0, fmt.Errorf("empty duration string")
        }
        matches := durationRE.FindStringSubmatch(durationStr)
-       if len(matches) != 3 {
+       if matches == nil {
                return 0, fmt.Errorf("not a valid duration string: %q", durationStr)
        }
-       var (
-               n, _ = strconv.Atoi(matches[1])
-               dur  = time.Duration(n) * time.Millisecond
-       )
-       switch unit := matches[2]; unit {
-       case "y":
-               dur *= 1000 * 60 * 60 * 24 * 365
-       case "w":
-               dur *= 1000 * 60 * 60 * 24 * 7
-       case "d":
-               dur *= 1000 * 60 * 60 * 24
-       case "h":
-               dur *= 1000 * 60 * 60
-       case "m":
-               dur *= 1000 * 60
-       case "s":
-               dur *= 1000
-       case "ms":
-               // Value already correct
-       default:
-               return 0, fmt.Errorf("invalid time unit in duration string: %q", unit)
+       var dur time.Duration
+
+       // Parse the match at pos `pos` in the regex and use `mult` to turn that
+       // into ms, then add that value to the total parsed duration.
+       m := func(pos int, mult time.Duration) {
+               if matches[pos] == "" {
+                       return
+               }
+               n, _ := strconv.Atoi(matches[pos])
+               d := time.Duration(n) * time.Millisecond
+               dur += d * mult
        }
+
+       m(2, 1000*60*60*24*365) // y
+       m(4, 1000*60*60*24*7)   // w
+       m(6, 1000*60*60*24)     // d
+       m(8, 1000*60*60)        // h
+       m(10, 1000*60)          // m
+       m(12, 1000)             // s
+       m(14, 1)                // ms
+
        return Duration(dur), nil
 }
 
 func (d Duration) String() string {
        var (
-               ms   = int64(time.Duration(d) / time.Millisecond)
-               unit = "ms"
+               ms = int64(time.Duration(d) / time.Millisecond)
+               r  = ""
        )
        if ms == 0 {
                return "0s"
        }
-       factors := map[string]int64{
-               "y":  1000 * 60 * 60 * 24 * 365,
-               "w":  1000 * 60 * 60 * 24 * 7,
-               "d":  1000 * 60 * 60 * 24,
-               "h":  1000 * 60 * 60,
-               "m":  1000 * 60,
-               "s":  1000,
-               "ms": 1,
-       }
 
-       switch int64(0) {
-       case ms % factors["y"]:
-               unit = "y"
-       case ms % factors["w"]:
-               unit = "w"
-       case ms % factors["d"]:
-               unit = "d"
-       case ms % factors["h"]:
-               unit = "h"
-       case ms % factors["m"]:
-               unit = "m"
-       case ms % factors["s"]:
-               unit = "s"
+       f := func(unit string, mult int64, exact bool) {
+               if exact && ms%mult != 0 {
+                       return
+               }
+               if v := ms / mult; v > 0 {
+                       r += fmt.Sprintf("%d%s", v, unit)
+                       ms -= v * mult
+               }
        }
-       return fmt.Sprintf("%v%v", ms/factors[unit], unit)
+
+       // Only format years and weeks if the remainder is zero, as it is often
+       // easier to read 90d than 12w6d.
+       f("y", 1000*60*60*24*365, true)
+       f("w", 1000*60*60*24*7, true)
+
+       f("d", 1000*60*60*24, false)
+       f("h", 1000*60*60, false)
+       f("m", 1000*60, false)
+       f("s", 1000, false)
+       f("ms", 1, false)
+
+       return r
 }
 
 // MarshalYAML implements the yaml.Marshaler interface.
index ac9af1febd9d293c5183a5f24c9ee9b6bd49df77..3e2a7ee50e4b2180820831764cfa05dc97f0f160 100644 (file)
@@ -61,6 +61,7 @@ var versionInfoTmpl = `
   build user:       {{.buildUser}}
   build date:       {{.buildDate}}
   go version:       {{.goVersion}}
+  platform:         {{.platform}}
 `
 
 // Print returns version information.
@@ -73,6 +74,7 @@ func Print(program string) string {
                "buildUser": BuildUser,
                "buildDate": BuildDate,
                "goVersion": GoVersion,
+               "platform":  runtime.GOOS + "/" + runtime.GOARCH,
        }
        t := template.Must(template.New("version").Parse(versionInfoTmpl))
 
diff --git a/vendor/github.com/prometheus/exporter-toolkit/LICENSE b/vendor/github.com/prometheus/exporter-toolkit/LICENSE
new file mode 100644 (file)
index 0000000..261eeb9
--- /dev/null
@@ -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.
diff --git a/vendor/github.com/prometheus/exporter-toolkit/https/README.md b/vendor/github.com/prometheus/exporter-toolkit/https/README.md
new file mode 100644 (file)
index 0000000..e6c9896
--- /dev/null
@@ -0,0 +1,81 @@
+# HTTPS Package for Prometheus
+
+The `https` directory contains a Go package and a sample configuration file for
+running `node_exporter` with HTTPS instead of HTTP. We currently support TLS 1.3
+and TLS 1.2.
+
+To run a server with TLS, use the flag `--web.config`.
+
+e.g. `./node_exporter --web.config="web-config.yml"`
+If the config is kept within the https directory.
+
+The config file should be written in YAML format, and is reloaded on each connection to check for new certificates and/or authentication policy.
+
+## Sample Config
+
+```
+tls_server_config:
+  # Certificate and key files for server to use to authenticate to client.
+  cert_file: <filename>
+  key_file: <filename>
+
+  # Server policy for client authentication. Maps to ClientAuth Policies.
+  # For more detail on clientAuth options: [ClientAuthType](https://golang.org/pkg/crypto/tls/#ClientAuthType)
+  [ client_auth_type: <string> | default = "NoClientCert" ]
+
+  # CA certificate for client certificate authentication to the server.
+  [ client_ca_file: <filename> ]
+
+  # Minimum TLS version that is acceptable.
+  [ min_version: <string> | default = "TLS12" ]
+
+  # Maximum TLS version that is acceptable.
+  [ max_version: <string> | default = "TLS13" ]
+
+  # List of supported cipher suites for TLS versions up to TLS 1.2. If empty,
+  # Go default cipher suites are used. Available cipher suites are documented
+  # in the go documentation:
+  # https://golang.org/pkg/crypto/tls/#pkg-constants
+  [ cipher_suites:
+    [ - <string> ] ]
+
+  # prefer_server_cipher_suites controls whether the server selects the
+  # client's most preferred ciphersuite, or the server's most preferred
+  # ciphersuite. If true then the server's preference, as expressed in
+  # the order of elements in cipher_suites, is used.
+  [ prefer_server_cipher_suites: <bool> | default = true ]
+
+  # Elliptic curves that will be used in an ECDHE handshake, in preference
+  # order. Available curves are documented in the go documentation:
+  # https://golang.org/pkg/crypto/tls/#CurveID
+  [ curve_preferences:
+    [ - <string> ] ]
+
+http_server_config:
+  # Enable HTTP/2 support. Note that HTTP/2 is only supported with TLS.
+  # This can not be changed on the fly.
+  [ http2: <bool> | default = true ]
+
+# Usernames and hashed passwords that have full access to the web
+# server via basic authentication. If empty, no basic authentication is
+# required. Passwords are hashed with bcrypt.
+basic_auth_users:
+  [ <string>: <secret> ... ]
+```
+
+## About bcrypt
+
+There are several tools out there to generate bcrypt passwords, e.g.
+[htpasswd](https://httpd.apache.org/docs/2.4/programs/htpasswd.html):
+
+`htpasswd -nBC 10 "" | tr -d ':\n'`
+
+That command will prompt you for a password and output the hashed password,
+which will look something like:
+`$2y$10$X0h1gDsPszWURQaxFh.zoubFi6DXncSjhoQNJgRrnGs7EsimhC7zG`
+
+The cost (10 in the example) influences the time it takes for computing the
+hash. A higher cost will en up slowing down the authentication process.
+Depending on the machine, a cost of 10 will take about ~70ms where a cost of
+18 can take up to a few seconds. That hash will be computed on every
+password-protected request.
diff --git a/vendor/github.com/prometheus/exporter-toolkit/https/kingpinflag/flag.go b/vendor/github.com/prometheus/exporter-toolkit/https/kingpinflag/flag.go
new file mode 100644 (file)
index 0000000..8cf66ea
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2020 The Prometheus 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 kingpinflag
+
+import (
+       "gopkg.in/alecthomas/kingpin.v2"
+)
+
+// AddFlags adds the flags used by this package to the Kingpin application.
+// To use the default Kingpin application, call AddFlags(kingpin.CommandLine)
+func AddFlags(a *kingpin.Application) *string {
+       return a.Flag(
+               "web.config.file",
+               "[EXPERIMENTAL] Path to configuration file that can enable TLS or authentication.",
+       ).Default("").String()
+}
diff --git a/vendor/github.com/prometheus/exporter-toolkit/https/tls_config.go b/vendor/github.com/prometheus/exporter-toolkit/https/tls_config.go
new file mode 100644 (file)
index 0000000..192e533
--- /dev/null
@@ -0,0 +1,343 @@
+// Copyright 2019 The Prometheus 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 https allows the implementation of TLS.
+package https
+
+import (
+       "crypto/tls"
+       "crypto/x509"
+       "fmt"
+       "io/ioutil"
+       "net"
+       "net/http"
+       "path/filepath"
+
+       "github.com/go-kit/kit/log"
+       "github.com/go-kit/kit/log/level"
+       "github.com/pkg/errors"
+       config_util "github.com/prometheus/common/config"
+       "gopkg.in/yaml.v2"
+)
+
+var (
+       errNoTLSConfig = errors.New("TLS config is not present")
+)
+
+type Config struct {
+       TLSConfig  TLSStruct                     `yaml:"tls_server_config"`
+       HTTPConfig HTTPStruct                    `yaml:"http_server_config"`
+       Users      map[string]config_util.Secret `yaml:"basic_auth_users"`
+}
+
+type TLSStruct struct {
+       TLSCertPath              string     `yaml:"cert_file"`
+       TLSKeyPath               string     `yaml:"key_file"`
+       ClientAuth               string     `yaml:"client_auth_type"`
+       ClientCAs                string     `yaml:"client_ca_file"`
+       CipherSuites             []cipher   `yaml:"cipher_suites"`
+       CurvePreferences         []curve    `yaml:"curve_preferences"`
+       MinVersion               tlsVersion `yaml:"min_version"`
+       MaxVersion               tlsVersion `yaml:"max_version"`
+       PreferServerCipherSuites bool       `yaml:"prefer_server_cipher_suites"`
+}
+
+// SetDirectory joins any relative file paths with dir.
+func (t *TLSStruct) SetDirectory(dir string) {
+       t.TLSCertPath = config_util.JoinDir(dir, t.TLSCertPath)
+       t.TLSKeyPath = config_util.JoinDir(dir, t.TLSKeyPath)
+       t.ClientCAs = config_util.JoinDir(dir, t.ClientCAs)
+}
+
+type HTTPStruct struct {
+       HTTP2 bool `yaml:"http2"`
+}
+
+func getConfig(configPath string) (*Config, error) {
+       content, err := ioutil.ReadFile(configPath)
+       if err != nil {
+               return nil, err
+       }
+       c := &Config{
+               TLSConfig: TLSStruct{
+                       MinVersion:               tls.VersionTLS12,
+                       MaxVersion:               tls.VersionTLS13,
+                       PreferServerCipherSuites: true,
+               },
+               HTTPConfig: HTTPStruct{HTTP2: true},
+       }
+       err = yaml.UnmarshalStrict(content, c)
+       c.TLSConfig.SetDirectory(filepath.Dir(configPath))
+       return c, err
+}
+
+func getTLSConfig(configPath string) (*tls.Config, error) {
+       c, err := getConfig(configPath)
+       if err != nil {
+               return nil, err
+       }
+       return ConfigToTLSConfig(&c.TLSConfig)
+}
+
+// ConfigToTLSConfig generates the golang tls.Config from the TLSStruct config.
+func ConfigToTLSConfig(c *TLSStruct) (*tls.Config, error) {
+       if c.TLSCertPath == "" && c.TLSKeyPath == "" && c.ClientAuth == "" && c.ClientCAs == "" {
+               return nil, errNoTLSConfig
+       }
+
+       if c.TLSCertPath == "" {
+               return nil, errors.New("missing cert_file")
+       }
+
+       if c.TLSKeyPath == "" {
+               return nil, errors.New("missing key_file")
+       }
+
+       loadCert := func() (*tls.Certificate, error) {
+               cert, err := tls.LoadX509KeyPair(c.TLSCertPath, c.TLSKeyPath)
+               if err != nil {
+                       return nil, errors.Wrap(err, "failed to load X509KeyPair")
+               }
+               return &cert, nil
+       }
+
+       // Confirm that certificate and key paths are valid.
+       if _, err := loadCert(); err != nil {
+               return nil, err
+       }
+
+       cfg := &tls.Config{
+               MinVersion:               (uint16)(c.MinVersion),
+               MaxVersion:               (uint16)(c.MaxVersion),
+               PreferServerCipherSuites: c.PreferServerCipherSuites,
+       }
+
+       cfg.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
+               return loadCert()
+       }
+
+       var cf []uint16
+       for _, c := range c.CipherSuites {
+               cf = append(cf, (uint16)(c))
+       }
+       if len(cf) > 0 {
+               cfg.CipherSuites = cf
+       }
+
+       var cp []tls.CurveID
+       for _, c := range c.CurvePreferences {
+               cp = append(cp, (tls.CurveID)(c))
+       }
+       if len(cp) > 0 {
+               cfg.CurvePreferences = cp
+       }
+
+       if c.ClientCAs != "" {
+               clientCAPool := x509.NewCertPool()
+               clientCAFile, err := ioutil.ReadFile(c.ClientCAs)
+               if err != nil {
+                       return nil, err
+               }
+               clientCAPool.AppendCertsFromPEM(clientCAFile)
+               cfg.ClientCAs = clientCAPool
+       }
+
+       switch c.ClientAuth {
+       case "RequestClientCert":
+               cfg.ClientAuth = tls.RequestClientCert
+       case "RequireClientCert":
+               cfg.ClientAuth = tls.RequireAnyClientCert
+       case "VerifyClientCertIfGiven":
+               cfg.ClientAuth = tls.VerifyClientCertIfGiven
+       case "RequireAndVerifyClientCert":
+               cfg.ClientAuth = tls.RequireAndVerifyClientCert
+       case "", "NoClientCert":
+               cfg.ClientAuth = tls.NoClientCert
+       default:
+               return nil, errors.New("Invalid ClientAuth: " + c.ClientAuth)
+       }
+
+       if c.ClientCAs != "" && cfg.ClientAuth == tls.NoClientCert {
+               return nil, errors.New("Client CA's have been configured without a Client Auth Policy")
+       }
+
+       return cfg, nil
+}
+
+// Listen starts the server on the given address. Based on the file
+// tlsConfigPath, TLS or basic auth could be enabled.
+func Listen(server *http.Server, tlsConfigPath string, logger log.Logger) error {
+       listener, err := net.Listen("tcp", server.Addr)
+       if err != nil {
+               return err
+       }
+       defer listener.Close()
+       return Serve(listener, server, tlsConfigPath, logger)
+}
+
+// Server starts the server on the given listener. Based on the file
+// tlsConfigPath, TLS or basic auth could be enabled.
+func Serve(l net.Listener, server *http.Server, tlsConfigPath string, logger log.Logger) error {
+       if tlsConfigPath == "" {
+               level.Info(logger).Log("msg", "TLS is disabled.", "http2", false)
+               return server.Serve(l)
+       }
+
+       if err := validateUsers(tlsConfigPath); err != nil {
+               return err
+       }
+
+       // Setup basic authentication.
+       var handler http.Handler = http.DefaultServeMux
+       if server.Handler != nil {
+               handler = server.Handler
+       }
+       server.Handler = &userAuthRoundtrip{
+               tlsConfigPath: tlsConfigPath,
+               logger:        logger,
+               handler:       handler,
+       }
+
+       c, err := getConfig(tlsConfigPath)
+       if err != nil {
+               return err
+       }
+
+       config, err := ConfigToTLSConfig(&c.TLSConfig)
+       switch err {
+       case nil:
+               if !c.HTTPConfig.HTTP2 {
+                       server.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler))
+               }
+               // Valid TLS config.
+               level.Info(logger).Log("msg", "TLS is enabled.", "http2", c.HTTPConfig.HTTP2)
+       case errNoTLSConfig:
+               // No TLS config, back to plain HTTP.
+               level.Info(logger).Log("msg", "TLS is disabled.", "http2", false)
+               return server.Serve(l)
+       default:
+               // Invalid TLS config.
+               return err
+       }
+
+       server.TLSConfig = config
+
+       // Set the GetConfigForClient method of the HTTPS server so that the config
+       // and certs are reloaded on new connections.
+       server.TLSConfig.GetConfigForClient = func(*tls.ClientHelloInfo) (*tls.Config, error) {
+               return getTLSConfig(tlsConfigPath)
+       }
+       return server.ServeTLS(l, "", "")
+}
+
+// Validate configuration file by reading the configuration and the certificates.
+func Validate(tlsConfigPath string) error {
+       if tlsConfigPath == "" {
+               return nil
+       }
+       if err := validateUsers(tlsConfigPath); err != nil {
+               return err
+       }
+       c, err := getConfig(tlsConfigPath)
+       if err != nil {
+               return err
+       }
+       _, err = ConfigToTLSConfig(&c.TLSConfig)
+       if err == errNoTLSConfig {
+               return nil
+       }
+       return err
+}
+
+type cipher uint16
+
+func (c *cipher) UnmarshalYAML(unmarshal func(interface{}) error) error {
+       var s string
+       err := unmarshal((*string)(&s))
+       if err != nil {
+               return err
+       }
+       for _, cs := range tls.CipherSuites() {
+               if cs.Name == s {
+                       *c = (cipher)(cs.ID)
+                       return nil
+               }
+       }
+       return errors.New("unknown cipher: " + s)
+}
+
+func (c cipher) MarshalYAML() (interface{}, error) {
+       return tls.CipherSuiteName((uint16)(c)), nil
+}
+
+type curve tls.CurveID
+
+var curves = map[string]curve{
+       "CurveP256": (curve)(tls.CurveP256),
+       "CurveP384": (curve)(tls.CurveP384),
+       "CurveP521": (curve)(tls.CurveP521),
+       "X25519":    (curve)(tls.X25519),
+}
+
+func (c *curve) UnmarshalYAML(unmarshal func(interface{}) error) error {
+       var s string
+       err := unmarshal((*string)(&s))
+       if err != nil {
+               return err
+       }
+       if curveid, ok := curves[s]; ok {
+               *c = curveid
+               return nil
+       }
+       return errors.New("unknown curve: " + s)
+}
+
+func (c *curve) MarshalYAML() (interface{}, error) {
+       for s, curveid := range curves {
+               if *c == curveid {
+                       return s, nil
+               }
+       }
+       return fmt.Sprintf("%v", c), nil
+}
+
+type tlsVersion uint16
+
+var tlsVersions = map[string]tlsVersion{
+       "TLS13": (tlsVersion)(tls.VersionTLS13),
+       "TLS12": (tlsVersion)(tls.VersionTLS12),
+       "TLS11": (tlsVersion)(tls.VersionTLS11),
+       "TLS10": (tlsVersion)(tls.VersionTLS10),
+}
+
+func (tv *tlsVersion) UnmarshalYAML(unmarshal func(interface{}) error) error {
+       var s string
+       err := unmarshal((*string)(&s))
+       if err != nil {
+               return err
+       }
+       if v, ok := tlsVersions[s]; ok {
+               *tv = v
+               return nil
+       }
+       return errors.New("unknown TLS version: " + s)
+}
+
+func (tv *tlsVersion) MarshalYAML() (interface{}, error) {
+       for s, v := range tlsVersions {
+               if *tv == v {
+                       return s, nil
+               }
+       }
+       return fmt.Sprintf("%v", tv), nil
+}
diff --git a/vendor/github.com/prometheus/exporter-toolkit/https/users.go b/vendor/github.com/prometheus/exporter-toolkit/https/users.go
new file mode 100644 (file)
index 0000000..317b0e4
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright 2020 The Prometheus 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 https
+
+import (
+       "net/http"
+
+       "github.com/go-kit/kit/log"
+       "golang.org/x/crypto/bcrypt"
+)
+
+func validateUsers(configPath string) error {
+       c, err := getConfig(configPath)
+       if err != nil {
+               return err
+       }
+
+       for _, p := range c.Users {
+               _, err = bcrypt.Cost([]byte(p))
+               if err != nil {
+                       return err
+               }
+       }
+
+       return nil
+}
+
+type userAuthRoundtrip struct {
+       tlsConfigPath string
+       handler       http.Handler
+       logger        log.Logger
+}
+
+func (u *userAuthRoundtrip) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+       c, err := getConfig(u.tlsConfigPath)
+       if err != nil {
+               u.logger.Log("msg", "Unable to parse configuration", "err", err)
+               http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+               return
+       }
+
+       if len(c.Users) == 0 {
+               u.handler.ServeHTTP(w, r)
+               return
+       }
+
+       user, pass, auth := r.BasicAuth()
+       if auth {
+               if hashedPassword, ok := c.Users[user]; ok {
+                       if err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(pass)); err == nil {
+                               u.handler.ServeHTTP(w, r)
+                               return
+                       }
+               }
+       }
+
+       w.Header().Set("WWW-Authenticate", "Basic")
+       http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
+}
diff --git a/vendor/github.com/prometheus/exporter-toolkit/https/web-config.yml b/vendor/github.com/prometheus/exporter-toolkit/https/web-config.yml
new file mode 100644 (file)
index 0000000..7d40d9b
--- /dev/null
@@ -0,0 +1,6 @@
+# Minimal TLS configuration example. Additionally, a certificate and a key file
+# are needed.
+tls_server_config:
+  cert_file: server.crt
+  key_file: server.key
+
index b978dfc50d2f32603e8e7e09a18baba6ccf98cf5..9320176ca24f423b5e90adb69df97c6829495c7d 100644 (file)
@@ -150,6 +150,17 @@ else
        $(GO) get $(GOOPTS) -t ./...
 endif
 
+.PHONY: update-go-deps
+update-go-deps:
+       @echo ">> updating Go dependencies"
+       @for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \
+               $(GO) get $$m; \
+       done
+       GO111MODULE=$(GO111MODULE) $(GO) mod tidy
+ifneq (,$(wildcard vendor))
+       GO111MODULE=$(GO111MODULE) $(GO) mod vendor
+endif
+
 .PHONY: common-test-short
 common-test-short: $(GOTEST_DIR)
        @echo ">> running short tests"
index 2e02215528f0908646d0e62769a03286bc409802..31d42f7124c36ffd6fc642ed153148cd7d182658 100644 (file)
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// +build linux
+
 package procfs
 
 import (
        "bufio"
        "bytes"
+       "errors"
+       "regexp"
        "strconv"
        "strings"
 
@@ -52,6 +56,11 @@ type CPUInfo struct {
        PowerManagement string
 }
 
+var (
+       cpuinfoClockRegexp          = regexp.MustCompile(`([\d.]+)`)
+       cpuinfoS390XProcessorRegexp = regexp.MustCompile(`^processor\s+(\d+):.*`)
+)
+
 // CPUInfo returns information about current system CPUs.
 // See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
 func (fs FS) CPUInfo() ([]CPUInfo, error) {
@@ -62,14 +71,26 @@ func (fs FS) CPUInfo() ([]CPUInfo, error) {
        return parseCPUInfo(data)
 }
 
-// parseCPUInfo parses data from /proc/cpuinfo
-func parseCPUInfo(info []byte) ([]CPUInfo, error) {
-       cpuinfo := []CPUInfo{}
-       i := -1
+func parseCPUInfoX86(info []byte) ([]CPUInfo, error) {
        scanner := bufio.NewScanner(bytes.NewReader(info))
+
+       // find the first "processor" line
+       firstLine := firstNonEmptyLine(scanner)
+       if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") {
+               return nil, errors.New("invalid cpuinfo file: " + firstLine)
+       }
+       field := strings.SplitN(firstLine, ": ", 2)
+       v, err := strconv.ParseUint(field[1], 0, 32)
+       if err != nil {
+               return nil, err
+       }
+       firstcpu := CPUInfo{Processor: uint(v)}
+       cpuinfo := []CPUInfo{firstcpu}
+       i := 0
+
        for scanner.Scan() {
                line := scanner.Text()
-               if strings.TrimSpace(line) == "" {
+               if !strings.Contains(line, ":") {
                        continue
                }
                field := strings.SplitN(line, ": ", 2)
@@ -82,7 +103,7 @@ func parseCPUInfo(info []byte) ([]CPUInfo, error) {
                                return nil, err
                        }
                        cpuinfo[i].Processor = uint(v)
-               case "vendor_id":
+               case "vendor", "vendor_id":
                        cpuinfo[i].VendorID = field[1]
                case "cpu family":
                        cpuinfo[i].CPUFamily = field[1]
@@ -163,5 +184,237 @@ func parseCPUInfo(info []byte) ([]CPUInfo, error) {
                }
        }
        return cpuinfo, nil
+}
+
+func parseCPUInfoARM(info []byte) ([]CPUInfo, error) {
+       scanner := bufio.NewScanner(bytes.NewReader(info))
+
+       firstLine := firstNonEmptyLine(scanner)
+       match, _ := regexp.MatchString("^[Pp]rocessor", firstLine)
+       if !match || !strings.Contains(firstLine, ":") {
+               return nil, errors.New("invalid cpuinfo file: " + firstLine)
+       }
+       field := strings.SplitN(firstLine, ": ", 2)
+       cpuinfo := []CPUInfo{}
+       featuresLine := ""
+       commonCPUInfo := CPUInfo{}
+       i := 0
+       if strings.TrimSpace(field[0]) == "Processor" {
+               commonCPUInfo = CPUInfo{ModelName: field[1]}
+               i = -1
+       } else {
+               v, err := strconv.ParseUint(field[1], 0, 32)
+               if err != nil {
+                       return nil, err
+               }
+               firstcpu := CPUInfo{Processor: uint(v)}
+               cpuinfo = []CPUInfo{firstcpu}
+       }
+
+       for scanner.Scan() {
+               line := scanner.Text()
+               if !strings.Contains(line, ":") {
+                       continue
+               }
+               field := strings.SplitN(line, ": ", 2)
+               switch strings.TrimSpace(field[0]) {
+               case "processor":
+                       cpuinfo = append(cpuinfo, commonCPUInfo) // start of the next processor
+                       i++
+                       v, err := strconv.ParseUint(field[1], 0, 32)
+                       if err != nil {
+                               return nil, err
+                       }
+                       cpuinfo[i].Processor = uint(v)
+               case "BogoMIPS":
+                       if i == -1 {
+                               cpuinfo = append(cpuinfo, commonCPUInfo) // There is only one processor
+                               i++
+                               cpuinfo[i].Processor = 0
+                       }
+                       v, err := strconv.ParseFloat(field[1], 64)
+                       if err != nil {
+                               return nil, err
+                       }
+                       cpuinfo[i].BogoMips = v
+               case "Features":
+                       featuresLine = line
+               case "model name":
+                       cpuinfo[i].ModelName = field[1]
+               }
+       }
+       fields := strings.SplitN(featuresLine, ": ", 2)
+       for i := range cpuinfo {
+               cpuinfo[i].Flags = strings.Fields(fields[1])
+       }
+       return cpuinfo, nil
+
+}
+
+func parseCPUInfoS390X(info []byte) ([]CPUInfo, error) {
+       scanner := bufio.NewScanner(bytes.NewReader(info))
+
+       firstLine := firstNonEmptyLine(scanner)
+       if !strings.HasPrefix(firstLine, "vendor_id") || !strings.Contains(firstLine, ":") {
+               return nil, errors.New("invalid cpuinfo file: " + firstLine)
+       }
+       field := strings.SplitN(firstLine, ": ", 2)
+       cpuinfo := []CPUInfo{}
+       commonCPUInfo := CPUInfo{VendorID: field[1]}
+
+       for scanner.Scan() {
+               line := scanner.Text()
+               if !strings.Contains(line, ":") {
+                       continue
+               }
+               field := strings.SplitN(line, ": ", 2)
+               switch strings.TrimSpace(field[0]) {
+               case "bogomips per cpu":
+                       v, err := strconv.ParseFloat(field[1], 64)
+                       if err != nil {
+                               return nil, err
+                       }
+                       commonCPUInfo.BogoMips = v
+               case "features":
+                       commonCPUInfo.Flags = strings.Fields(field[1])
+               }
+               if strings.HasPrefix(line, "processor") {
+                       match := cpuinfoS390XProcessorRegexp.FindStringSubmatch(line)
+                       if len(match) < 2 {
+                               return nil, errors.New("Invalid line found in cpuinfo: " + line)
+                       }
+                       cpu := commonCPUInfo
+                       v, err := strconv.ParseUint(match[1], 0, 32)
+                       if err != nil {
+                               return nil, err
+                       }
+                       cpu.Processor = uint(v)
+                       cpuinfo = append(cpuinfo, cpu)
+               }
+               if strings.HasPrefix(line, "cpu number") {
+                       break
+               }
+       }
+
+       i := 0
+       for scanner.Scan() {
+               line := scanner.Text()
+               if !strings.Contains(line, ":") {
+                       continue
+               }
+               field := strings.SplitN(line, ": ", 2)
+               switch strings.TrimSpace(field[0]) {
+               case "cpu number":
+                       i++
+               case "cpu MHz dynamic":
+                       clock := cpuinfoClockRegexp.FindString(strings.TrimSpace(field[1]))
+                       v, err := strconv.ParseFloat(clock, 64)
+                       if err != nil {
+                               return nil, err
+                       }
+                       cpuinfo[i].CPUMHz = v
+               }
+       }
+
+       return cpuinfo, nil
+}
+
+func parseCPUInfoMips(info []byte) ([]CPUInfo, error) {
+       scanner := bufio.NewScanner(bytes.NewReader(info))
+
+       // find the first "processor" line
+       firstLine := firstNonEmptyLine(scanner)
+       if !strings.HasPrefix(firstLine, "system type") || !strings.Contains(firstLine, ":") {
+               return nil, errors.New("invalid cpuinfo file: " + firstLine)
+       }
+       field := strings.SplitN(firstLine, ": ", 2)
+       cpuinfo := []CPUInfo{}
+       systemType := field[1]
+
+       i := 0
+
+       for scanner.Scan() {
+               line := scanner.Text()
+               if !strings.Contains(line, ":") {
+                       continue
+               }
+               field := strings.SplitN(line, ": ", 2)
+               switch strings.TrimSpace(field[0]) {
+               case "processor":
+                       v, err := strconv.ParseUint(field[1], 0, 32)
+                       if err != nil {
+                               return nil, err
+                       }
+                       i = int(v)
+                       cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor
+                       cpuinfo[i].Processor = uint(v)
+                       cpuinfo[i].VendorID = systemType
+               case "cpu model":
+                       cpuinfo[i].ModelName = field[1]
+               case "BogoMIPS":
+                       v, err := strconv.ParseFloat(field[1], 64)
+                       if err != nil {
+                               return nil, err
+                       }
+                       cpuinfo[i].BogoMips = v
+               }
+       }
+       return cpuinfo, nil
+}
+
+func parseCPUInfoPPC(info []byte) ([]CPUInfo, error) {
+       scanner := bufio.NewScanner(bytes.NewReader(info))
+
+       firstLine := firstNonEmptyLine(scanner)
+       if !strings.HasPrefix(firstLine, "processor") || !strings.Contains(firstLine, ":") {
+               return nil, errors.New("invalid cpuinfo file: " + firstLine)
+       }
+       field := strings.SplitN(firstLine, ": ", 2)
+       v, err := strconv.ParseUint(field[1], 0, 32)
+       if err != nil {
+               return nil, err
+       }
+       firstcpu := CPUInfo{Processor: uint(v)}
+       cpuinfo := []CPUInfo{firstcpu}
+       i := 0
+
+       for scanner.Scan() {
+               line := scanner.Text()
+               if !strings.Contains(line, ":") {
+                       continue
+               }
+               field := strings.SplitN(line, ": ", 2)
+               switch strings.TrimSpace(field[0]) {
+               case "processor":
+                       cpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor
+                       i++
+                       v, err := strconv.ParseUint(field[1], 0, 32)
+                       if err != nil {
+                               return nil, err
+                       }
+                       cpuinfo[i].Processor = uint(v)
+               case "cpu":
+                       cpuinfo[i].VendorID = field[1]
+               case "clock":
+                       clock := cpuinfoClockRegexp.FindString(strings.TrimSpace(field[1]))
+                       v, err := strconv.ParseFloat(clock, 64)
+                       if err != nil {
+                               return nil, err
+                       }
+                       cpuinfo[i].CPUMHz = v
+               }
+       }
+       return cpuinfo, nil
+}
 
+// firstNonEmptyLine advances the scanner to the first non-empty line
+// and returns the contents of that line
+func firstNonEmptyLine(scanner *bufio.Scanner) string {
+       for scanner.Scan() {
+               line := scanner.Text()
+               if strings.TrimSpace(line) != "" {
+                       return line
+               }
+       }
+       return ""
 }
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_arm.go b/vendor/github.com/prometheus/procfs/cpuinfo_arm.go
new file mode 100644 (file)
index 0000000..8355507
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2020 The Prometheus 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.
+
+// +build linux
+
+package procfs
+
+var parseCPUInfo = parseCPUInfoARM
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_arm64.go b/vendor/github.com/prometheus/procfs/cpuinfo_arm64.go
new file mode 100644 (file)
index 0000000..4f5d172
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2020 The Prometheus 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.
+
+// +build linux
+// +build arm64
+
+package procfs
+
+var parseCPUInfo = parseCPUInfoARM
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_default.go b/vendor/github.com/prometheus/procfs/cpuinfo_default.go
new file mode 100644 (file)
index 0000000..d5bedf9
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2020 The Prometheus 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.
+
+// +build linux
+// +build 386 amd64
+
+package procfs
+
+var parseCPUInfo = parseCPUInfoX86
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_mips.go b/vendor/github.com/prometheus/procfs/cpuinfo_mips.go
new file mode 100644 (file)
index 0000000..22d93f8
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2020 The Prometheus 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.
+
+// +build linux
+
+package procfs
+
+var parseCPUInfo = parseCPUInfoMips
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_mips64.go b/vendor/github.com/prometheus/procfs/cpuinfo_mips64.go
new file mode 100644 (file)
index 0000000..22d93f8
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2020 The Prometheus 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.
+
+// +build linux
+
+package procfs
+
+var parseCPUInfo = parseCPUInfoMips
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_mips64le.go b/vendor/github.com/prometheus/procfs/cpuinfo_mips64le.go
new file mode 100644 (file)
index 0000000..22d93f8
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2020 The Prometheus 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.
+
+// +build linux
+
+package procfs
+
+var parseCPUInfo = parseCPUInfoMips
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_mipsle.go b/vendor/github.com/prometheus/procfs/cpuinfo_mipsle.go
new file mode 100644 (file)
index 0000000..22d93f8
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2020 The Prometheus 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.
+
+// +build linux
+
+package procfs
+
+var parseCPUInfo = parseCPUInfoMips
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_ppc64.go b/vendor/github.com/prometheus/procfs/cpuinfo_ppc64.go
new file mode 100644 (file)
index 0000000..64aee9c
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2020 The Prometheus 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.
+
+// +build linux
+
+package procfs
+
+var parseCPUInfo = parseCPUInfoPPC
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_ppc64le.go b/vendor/github.com/prometheus/procfs/cpuinfo_ppc64le.go
new file mode 100644 (file)
index 0000000..64aee9c
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2020 The Prometheus 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.
+
+// +build linux
+
+package procfs
+
+var parseCPUInfo = parseCPUInfoPPC
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go b/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go
new file mode 100644 (file)
index 0000000..26814ee
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2020 The Prometheus 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.
+
+// +build linux
+
+package procfs
+
+var parseCPUInfo = parseCPUInfoS390X
index 45a732155828c063a09ca3115f61b027a168d74d..868c8573d9254c88b01d202f8a88605a4ee71ddb 100644 (file)
@@ -173,6 +173,283 @@ Lines: 1
 411605849 93680043 79
 Mode: 644
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/26231/smaps
+Lines: 252
+00400000-00cb1000 r-xp 00000000 fd:01 952273                             /bin/alertmanager
+Size:               8900 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+Rss:                2952 kB
+Pss:                2952 kB
+Shared_Clean:          0 kB
+Shared_Dirty:          0 kB
+Private_Clean:      2952 kB
+Private_Dirty:         0 kB
+Referenced:         2864 kB
+Anonymous:             0 kB
+LazyFree:              0 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:                  0 kB
+SwapPss:               0 kB
+Locked:                0 kB
+VmFlags: rd ex mr mw me dw sd 
+00cb1000-016b0000 r--p 008b1000 fd:01 952273                             /bin/alertmanager
+Size:              10236 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+Rss:                6152 kB
+Pss:                6152 kB
+Shared_Clean:          0 kB
+Shared_Dirty:          0 kB
+Private_Clean:      6152 kB
+Private_Dirty:         0 kB
+Referenced:         5308 kB
+Anonymous:             0 kB
+LazyFree:              0 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:                  0 kB
+SwapPss:               0 kB
+Locked:                0 kB
+VmFlags: rd mr mw me dw sd 
+016b0000-0171a000 rw-p 012b0000 fd:01 952273                             /bin/alertmanager
+Size:                424 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+Rss:                 176 kB
+Pss:                 176 kB
+Shared_Clean:          0 kB
+Shared_Dirty:          0 kB
+Private_Clean:        84 kB
+Private_Dirty:        92 kB
+Referenced:          176 kB
+Anonymous:            92 kB
+LazyFree:              0 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:                 12 kB
+SwapPss:              12 kB
+Locked:                0 kB
+VmFlags: rd wr mr mw me dw ac sd 
+0171a000-0173f000 rw-p 00000000 00:00 0 
+Size:                148 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+Rss:                  76 kB
+Pss:                  76 kB
+Shared_Clean:          0 kB
+Shared_Dirty:          0 kB
+Private_Clean:         0 kB
+Private_Dirty:        76 kB
+Referenced:           76 kB
+Anonymous:            76 kB
+LazyFree:              0 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:                  0 kB
+SwapPss:               0 kB
+Locked:                0 kB
+VmFlags: rd wr mr mw me ac sd 
+c000000000-c000400000 rw-p 00000000 00:00 0 
+Size:               4096 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+Rss:                2564 kB
+Pss:                2564 kB
+Shared_Clean:          0 kB
+Shared_Dirty:          0 kB
+Private_Clean:        20 kB
+Private_Dirty:      2544 kB
+Referenced:         2544 kB
+Anonymous:          2564 kB
+LazyFree:              0 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:               1100 kB
+SwapPss:            1100 kB
+Locked:                0 kB
+VmFlags: rd wr mr mw me ac sd 
+c000400000-c001600000 rw-p 00000000 00:00 0 
+Size:              18432 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+Rss:               16024 kB
+Pss:               16024 kB
+Shared_Clean:          0 kB
+Shared_Dirty:          0 kB
+Private_Clean:      5864 kB
+Private_Dirty:     10160 kB
+Referenced:        11944 kB
+Anonymous:         16024 kB
+LazyFree:           5848 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:                440 kB
+SwapPss:             440 kB
+Locked:                0 kB
+VmFlags: rd wr mr mw me ac sd nh 
+c001600000-c004000000 rw-p 00000000 00:00 0 
+Size:              43008 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+Rss:                   0 kB
+Pss:                   0 kB
+Shared_Clean:          0 kB
+Shared_Dirty:          0 kB
+Private_Clean:         0 kB
+Private_Dirty:         0 kB
+Referenced:            0 kB
+Anonymous:             0 kB
+LazyFree:              0 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:                  0 kB
+SwapPss:               0 kB
+Locked:                0 kB
+VmFlags: rd wr mr mw me ac sd 
+7f0ab95ca000-7f0abbb7b000 rw-p 00000000 00:00 0 
+Size:              38596 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+Rss:                1992 kB
+Pss:                1992 kB
+Shared_Clean:          0 kB
+Shared_Dirty:          0 kB
+Private_Clean:       476 kB
+Private_Dirty:      1516 kB
+Referenced:         1828 kB
+Anonymous:          1992 kB
+LazyFree:              0 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:                384 kB
+SwapPss:             384 kB
+Locked:                0 kB
+VmFlags: rd wr mr mw me ac sd 
+7ffc07ecf000-7ffc07ef0000 rw-p 00000000 00:00 0                          [stack]
+Size:                132 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+Rss:                   8 kB
+Pss:                   8 kB
+Shared_Clean:          0 kB
+Shared_Dirty:          0 kB
+Private_Clean:         0 kB
+Private_Dirty:         8 kB
+Referenced:            8 kB
+Anonymous:             8 kB
+LazyFree:              0 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:                  4 kB
+SwapPss:               4 kB
+Locked:                0 kB
+VmFlags: rd wr mr mw me gd ac 
+7ffc07f9e000-7ffc07fa1000 r--p 00000000 00:00 0                          [vvar]
+Size:                 12 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+Rss:                   0 kB
+Pss:                   0 kB
+Shared_Clean:          0 kB
+Shared_Dirty:          0 kB
+Private_Clean:         0 kB
+Private_Dirty:         0 kB
+Referenced:            0 kB
+Anonymous:             0 kB
+LazyFree:              0 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:                  0 kB
+SwapPss:               0 kB
+Locked:                0 kB
+VmFlags: rd mr pf io de dd sd 
+7ffc07fa1000-7ffc07fa3000 r-xp 00000000 00:00 0                          [vdso]
+Size:                  8 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+Rss:                   4 kB
+Pss:                   0 kB
+Shared_Clean:          4 kB
+Shared_Dirty:          0 kB
+Private_Clean:         0 kB
+Private_Dirty:         0 kB
+Referenced:            4 kB
+Anonymous:             0 kB
+LazyFree:              0 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:                  0 kB
+SwapPss:               0 kB
+Locked:                0 kB
+VmFlags: rd ex mr mw me de sd 
+ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
+Size:                  4 kB
+KernelPageSize:        4 kB
+MMUPageSize:           4 kB
+Rss:                   0 kB
+Pss:                   0 kB
+Shared_Clean:          0 kB
+Shared_Dirty:          0 kB
+Private_Clean:         0 kB
+Private_Dirty:         0 kB
+Referenced:            0 kB
+Anonymous:             0 kB
+LazyFree:              0 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:                  0 kB
+SwapPss:               0 kB
+Locked:                0 kB
+VmFlags: rd ex 
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/26231/smaps_rollup
+Lines: 17
+00400000-ffffffffff601000 ---p 00000000 00:00 0                          [rollup]
+Rss:               29948 kB
+Pss:               29944 kB
+Shared_Clean:          4 kB
+Shared_Dirty:          0 kB
+Private_Clean:     15548 kB
+Private_Dirty:     14396 kB
+Referenced:        24752 kB
+Anonymous:         20756 kB
+LazyFree:           5848 kB
+AnonHugePages:         0 kB
+ShmemPmdMapped:        0 kB
+Shared_Hugetlb:        0 kB
+Private_Hugetlb:       0 kB
+Swap:               1940 kB
+SwapPss:            1940 kB
+Locked:                0 kB
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Path: fixtures/proc/26231/stat
 Lines: 1
 26231 (vim) R 5392 7446 5392 34835 7446 4218880 32533 309516 26 82 1677 44 158 99 20 0 1 0 82375 56274944 1981 18446744073709551615 4194304 6294284 140736914091744 140736914087944 139965136429984 0 0 12288 1870679807 0 0 0 17 0 0 0 31 0 0 8391624 8481048 16420864 140736914093252 140736914093279 140736914093279 140736914096107 0
@@ -235,6 +512,11 @@ voluntary_ctxt_switches:   4742839
 nonvoluntary_ctxt_switches:    1727500
 Mode: 644
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/26231/wchan
+Lines: 1
+poll_schedule_timeoutEOF
+Mode: 664
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Directory: fixtures/proc/26232
 Mode: 755
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -310,6 +592,11 @@ Lines: 1
 33 (ata_sff) S 2 0 0 0 -1 69238880 0 0 0 0 0 0 0 0 0 -20 1 0 5 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 18446744073709551615 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0
 Mode: 644
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/26232/wchan
+Lines: 1
+0EOF
+Mode: 664
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Directory: fixtures/proc/26233
 Mode: 755
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1554,7 +1841,7 @@ max keysize  : 32
 Mode: 444
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Path: fixtures/proc/diskstats
-Lines: 49
+Lines: 52
    1       0 ram0 0 0 0 0 0 0 0 0 0 0 0
    1       1 ram1 0 0 0 0 0 0 0 0 0 0 0
    1       2 ram2 0 0 0 0 0 0 0 0 0 0 0
@@ -1604,11 +1891,45 @@ Lines: 49
    8       0 sdb 326552 841 9657779 84 41822 2895 1972905 5007 0 60730 67070 68851 0 1925173784 11130
    8       1 sdb1 231 3 34466 4 24 23 106 0 0 64 64 0 0 0 0
    8       2 sdb2 326310 838 9622281 67 40726 2872 1972799 4924 0 58250 64567 68851 0 1925173784 11130
+   8       0 sdc 14202 71 579164 21861 2995 1589 180500 40875 0 11628 55200 0 0 0 0 127 182
+   8       1 sdc1 1027 0 13795 5021 2 0 4096 3 0 690 4579 0 0 0 0 0 0
+   8       2 sdc2 13126 71 561749 16802 2830 1589 176404 40620 0 10931 50449 0 0 0 0 0 0
 Mode: 664
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Directory: fixtures/proc/fs
 Mode: 755
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/proc/fs/fscache
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/fs/fscache/stats
+Lines: 24
+FS-Cache statistics
+Cookies: idx=3 dat=67877 spc=0
+Objects: alc=67473 nal=0 avl=67473 ded=388
+ChkAux : non=12 ok=33 upd=44 obs=55
+Pages  : mrk=547164 unc=364577
+Acquire: n=67880 nul=98 noc=25 ok=67780 nbf=39 oom=26
+Lookups: n=67473 neg=67470 pos=58 crt=67473 tmo=85
+Invals : n=14 run=13
+Updates: n=7 nul=3 run=8
+Relinqs: n=394 nul=1 wcr=2 rtr=3
+AttrChg: n=6 ok=5 nbf=4 oom=3 run=2
+Allocs : n=20 ok=19 wt=18 nbf=17 int=16
+Allocs : ops=15 owt=14 abt=13
+Retrvls: n=151959 ok=82823 wt=23467 nod=69136 nbf=15 int=69 oom=43
+Retrvls: ops=151959 owt=42747 abt=44
+Stores : n=225565 ok=225565 agn=12 nbf=13 oom=14
+Stores : ops=69156 run=294721 pgs=225565 rxd=225565 olm=43
+VmScan : nos=364512 gon=2 bsy=43 can=12 wt=66
+Ops    : pend=42753 run=221129 enq=628798 can=11 rej=88
+Ops    : ini=377538 dfr=27 rel=377538 gc=37
+CacheOp: alo=1 luo=2 luc=3 gro=4
+CacheOp: inv=5 upo=6 dro=7 pto=8 atc=9 syn=10
+CacheOp: rap=11 ras=12 alp=13 als=14 wrp=15 ucp=16 dsp=17
+CacheEv: nsp=18 stl=19 rtr=20 cul=21EOF
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Directory: fixtures/proc/fs/xfs
 Mode: 755
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -2025,6 +2346,32 @@ Mode: 644
 Directory: fixtures/proc/sys
 Mode: 775
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/proc/sys/kernel
+Mode: 775
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/proc/sys/kernel/random
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/kernel/random/entropy_avail
+Lines: 1
+3943
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/kernel/random/poolsize
+Lines: 1
+4096
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/kernel/random/urandom_min_reseed_secs
+Lines: 1
+60
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/proc/sys/kernel/random/write_wakeup_threshold
+Lines: 1
+3072
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Directory: fixtures/proc/sys/vm
 Mode: 775
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -2526,6 +2873,237 @@ Mode: 664
 Directory: fixtures/sys/block/sda
 Mode: 775
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/block/sda/queue
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/add_random
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/chunk_sectors
+Lines: 1
+0
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/dax
+Lines: 1
+0
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/discard_granularity
+Lines: 1
+0
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/discard_max_bytes
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/discard_max_hw_bytes
+Lines: 1
+0
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/discard_zeroes_data
+Lines: 1
+0
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/fua
+Lines: 1
+0
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/hw_sector_size
+Lines: 1
+512
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/io_poll
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/io_poll_delay
+Lines: 1
+-1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/io_timeout
+Lines: 1
+30000
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/block/sda/queue/iosched
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/iosched/back_seek_max
+Lines: 1
+16384
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/iosched/back_seek_penalty
+Lines: 1
+2
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/iosched/fifo_expire_async
+Lines: 1
+250
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/iosched/fifo_expire_sync
+Lines: 1
+125
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/iosched/low_latency
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/iosched/max_budget
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/iosched/slice_idle
+Lines: 1
+8
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/iosched/slice_idle_us
+Lines: 1
+8000
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/iosched/strict_guarantees
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/iosched/timeout_sync
+Lines: 1
+125
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/iostats
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/logical_block_size
+Lines: 1
+512
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/max_discard_segments
+Lines: 1
+1
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/max_hw_sectors_kb
+Lines: 1
+32767
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/max_integrity_segments
+Lines: 1
+0
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/max_sectors_kb
+Lines: 1
+1280
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/max_segment_size
+Lines: 1
+65536
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/max_segments
+Lines: 1
+168
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/minimum_io_size
+Lines: 1
+512
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/nomerges
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/nr_requests
+Lines: 1
+64
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/nr_zones
+Lines: 1
+0
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/optimal_io_size
+Lines: 1
+0
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/physical_block_size
+Lines: 1
+512
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/read_ahead_kb
+Lines: 1
+128
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/rotational
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/rq_affinity
+Lines: 1
+1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/scheduler
+Lines: 1
+mq-deadline kyber [bfq] none
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/wbt_lat_usec
+Lines: 1
+75000
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/write_cache
+Lines: 1
+write back
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/write_same_max_bytes
+Lines: 1
+0
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/write_zeroes_max_bytes
+Lines: 1
+0
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/block/sda/queue/zoned
+Lines: 1
+none
+Mode: 444
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Path: fixtures/sys/block/sda/stat
 Lines: 1
 9652963   396792 759304206   412943  8422549  6731723 286915323 13947418        0  5658367 19174573 1 2 3 12
@@ -2534,6 +3112,140 @@ Mode: 664
 Directory: fixtures/sys/class
 Mode: 775
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/fc_host
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/fc_host/host0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/dev_loss_tmo
+Lines: 1
+30
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/fabric_name
+Lines: 1
+0x0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/node_name
+Lines: 1
+0x2000e0071bce95f2
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/port_id
+Lines: 1
+0x000002
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/port_name
+Lines: 1
+0x1000e0071bce95f2
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/port_state
+Lines: 1
+Online
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/port_type
+Lines: 1
+Point-To-Point (direct nport connection)
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/speed
+Lines: 1
+16 Gbit
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/fc_host/host0/statistics
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/dumped_frames
+Lines: 1
+0xffffffffffffffff
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/error_frames
+Lines: 1
+0x0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/fcp_packet_aborts
+Lines: 1
+0x13
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/invalid_crc_count
+Lines: 1
+0x2
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/invalid_tx_word_count
+Lines: 1
+0x8
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/link_failure_count
+Lines: 1
+0x9
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/loss_of_signal_count
+Lines: 1
+0x11
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/loss_of_sync_count
+Lines: 1
+0x10
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/nos_count
+Lines: 1
+0x12
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/rx_frames
+Lines: 1
+0x3
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/rx_words
+Lines: 1
+0x4
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/seconds_since_last_reset
+Lines: 1
+0x7
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/tx_frames
+Lines: 1
+0x5
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/statistics/tx_words
+Lines: 1
+0x6
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/supported_classes
+Lines: 1
+Class 3
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/supported_speeds
+Lines: 1
+4 Gbit, 8 Gbit, 16 Gbit
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/fc_host/host0/symbolic_name
+Lines: 1
+Emulex SN1100E2P FV12.4.270.3 DV12.4.0.0. HN:gotest. OS:Linux
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Directory: fixtures/sys/class/infiniband
 Mode: 755
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -2564,6 +3276,11 @@ Mode: 755
 Directory: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters
 Mode: 755
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/VL15_dropped
+Lines: 1
+0
+Mode: 664
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/excessive_buffer_overrun_errors
 Lines: 1
 0
@@ -2665,6 +3382,11 @@ Mode: 755
 Directory: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters
 Mode: 755
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/VL15_dropped
+Lines: 1
+0
+Mode: 664
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/excessive_buffer_overrun_errors
 Lines: 1
 0
@@ -3109,7 +3831,7 @@ Mode: 664
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Path: fixtures/sys/class/thermal/thermal_zone1/temp
 Lines: 1
-44000
+-44000
 Mode: 664
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Path: fixtures/sys/class/thermal/thermal_zone1/type
@@ -4287,6 +5009,17 @@ Lines: 1
 0
 Mode: 644
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/writeback_rate_debug
+Lines: 7
+rate:           1.1M/sec
+dirty:          20.4G
+target:         20.4G
+proportional:   427.5k
+integral:       790.0k
+change:         321.5k/sec
+next io:        17ms
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/btree_cache_size
 Lines: 1
 0
diff --git a/vendor/github.com/prometheus/procfs/fscache.go b/vendor/github.com/prometheus/procfs/fscache.go
new file mode 100644 (file)
index 0000000..8783cf3
--- /dev/null
@@ -0,0 +1,422 @@
+// Copyright 2019 The Prometheus 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 procfs
+
+import (
+       "bufio"
+       "bytes"
+       "fmt"
+       "io"
+       "strconv"
+       "strings"
+
+       "github.com/prometheus/procfs/internal/util"
+)
+
+// Fscacheinfo represents fscache statistics.
+type Fscacheinfo struct {
+       // Number of index cookies allocated
+       IndexCookiesAllocated uint64
+       // data storage cookies allocated
+       DataStorageCookiesAllocated uint64
+       // Number of special cookies allocated
+       SpecialCookiesAllocated uint64
+       // Number of objects allocated
+       ObjectsAllocated uint64
+       // Number of object allocation failures
+       ObjectAllocationsFailure uint64
+       // Number of objects that reached the available state
+       ObjectsAvailable uint64
+       // Number of objects that reached the dead state
+       ObjectsDead uint64
+       // Number of objects that didn't have a coherency check
+       ObjectsWithoutCoherencyCheck uint64
+       // Number of objects that passed a coherency check
+       ObjectsWithCoherencyCheck uint64
+       // Number of objects that needed a coherency data update
+       ObjectsNeedCoherencyCheckUpdate uint64
+       // Number of objects that were declared obsolete
+       ObjectsDeclaredObsolete uint64
+       // Number of pages marked as being cached
+       PagesMarkedAsBeingCached uint64
+       // Number of uncache page requests seen
+       UncachePagesRequestSeen uint64
+       // Number of acquire cookie requests seen
+       AcquireCookiesRequestSeen uint64
+       // Number of acq reqs given a NULL parent
+       AcquireRequestsWithNullParent uint64
+       // Number of acq reqs rejected due to no cache available
+       AcquireRequestsRejectedNoCacheAvailable uint64
+       // Number of acq reqs succeeded
+       AcquireRequestsSucceeded uint64
+       // Number of acq reqs rejected due to error
+       AcquireRequestsRejectedDueToError uint64
+       // Number of acq reqs failed on ENOMEM
+       AcquireRequestsFailedDueToEnomem uint64
+       // Number of lookup calls made on cache backends
+       LookupsNumber uint64
+       // Number of negative lookups made
+       LookupsNegative uint64
+       // Number of positive lookups made
+       LookupsPositive uint64
+       // Number of objects created by lookup
+       ObjectsCreatedByLookup uint64
+       // Number of lookups timed out and requeued
+       LookupsTimedOutAndRequed uint64
+       InvalidationsNumber      uint64
+       InvalidationsRunning     uint64
+       // Number of update cookie requests seen
+       UpdateCookieRequestSeen uint64
+       // Number of upd reqs given a NULL parent
+       UpdateRequestsWithNullParent uint64
+       // Number of upd reqs granted CPU time
+       UpdateRequestsRunning uint64
+       // Number of relinquish cookie requests seen
+       RelinquishCookiesRequestSeen uint64
+       // Number of rlq reqs given a NULL parent
+       RelinquishCookiesWithNullParent uint64
+       // Number of rlq reqs waited on completion of creation
+       RelinquishRequestsWaitingCompleteCreation uint64
+       // Relinqs rtr
+       RelinquishRetries uint64
+       // Number of attribute changed requests seen
+       AttributeChangedRequestsSeen uint64
+       // Number of attr changed requests queued
+       AttributeChangedRequestsQueued uint64
+       // Number of attr changed rejected -ENOBUFS
+       AttributeChangedRejectDueToEnobufs uint64
+       // Number of attr changed failed -ENOMEM
+       AttributeChangedFailedDueToEnomem uint64
+       // Number of attr changed ops given CPU time
+       AttributeChangedOps uint64
+       // Number of allocation requests seen
+       AllocationRequestsSeen uint64
+       // Number of successful alloc reqs
+       AllocationOkRequests uint64
+       // Number of alloc reqs that waited on lookup completion
+       AllocationWaitingOnLookup uint64
+       // Number of alloc reqs rejected -ENOBUFS
+       AllocationsRejectedDueToEnobufs uint64
+       // Number of alloc reqs aborted -ERESTARTSYS
+       AllocationsAbortedDueToErestartsys uint64
+       // Number of alloc reqs submitted
+       AllocationOperationsSubmitted uint64
+       // Number of alloc reqs waited for CPU time
+       AllocationsWaitedForCPU uint64
+       // Number of alloc reqs aborted due to object death
+       AllocationsAbortedDueToObjectDeath uint64
+       // Number of retrieval (read) requests seen
+       RetrievalsReadRequests uint64
+       // Number of successful retr reqs
+       RetrievalsOk uint64
+       // Number of retr reqs that waited on lookup completion
+       RetrievalsWaitingLookupCompletion uint64
+       // Number of retr reqs returned -ENODATA
+       RetrievalsReturnedEnodata uint64
+       // Number of retr reqs rejected -ENOBUFS
+       RetrievalsRejectedDueToEnobufs uint64
+       // Number of retr reqs aborted -ERESTARTSYS
+       RetrievalsAbortedDueToErestartsys uint64
+       // Number of retr reqs failed -ENOMEM
+       RetrievalsFailedDueToEnomem uint64
+       // Number of retr reqs submitted
+       RetrievalsRequests uint64
+       // Number of retr reqs waited for CPU time
+       RetrievalsWaitingCPU uint64
+       // Number of retr reqs aborted due to object death
+       RetrievalsAbortedDueToObjectDeath uint64
+       // Number of storage (write) requests seen
+       StoreWriteRequests uint64
+       // Number of successful store reqs
+       StoreSuccessfulRequests uint64
+       // Number of store reqs on a page already pending storage
+       StoreRequestsOnPendingStorage uint64
+       // Number of store reqs rejected -ENOBUFS
+       StoreRequestsRejectedDueToEnobufs uint64
+       // Number of store reqs failed -ENOMEM
+       StoreRequestsFailedDueToEnomem uint64
+       // Number of store reqs submitted
+       StoreRequestsSubmitted uint64
+       // Number of store reqs granted CPU time
+       StoreRequestsRunning uint64
+       // Number of pages given store req processing time
+       StorePagesWithRequestsProcessing uint64
+       // Number of store reqs deleted from tracking tree
+       StoreRequestsDeleted uint64
+       // Number of store reqs over store limit
+       StoreRequestsOverStoreLimit uint64
+       // Number of release reqs against pages with no pending store
+       ReleaseRequestsAgainstPagesWithNoPendingStorage uint64
+       // Number of release reqs against pages stored by time lock granted
+       ReleaseRequestsAgainstPagesStoredByTimeLockGranted uint64
+       // Number of release reqs ignored due to in-progress store
+       ReleaseRequestsIgnoredDueToInProgressStore uint64
+       // Number of page stores cancelled due to release req
+       PageStoresCancelledByReleaseRequests uint64
+       VmscanWaiting                        uint64
+       // Number of times async ops added to pending queues
+       OpsPending uint64
+       // Number of times async ops given CPU time
+       OpsRunning uint64
+       // Number of times async ops queued for processing
+       OpsEnqueued uint64
+       // Number of async ops cancelled
+       OpsCancelled uint64
+       // Number of async ops rejected due to object lookup/create failure
+       OpsRejected uint64
+       // Number of async ops initialised
+       OpsInitialised uint64
+       // Number of async ops queued for deferred release
+       OpsDeferred uint64
+       // Number of async ops released (should equal ini=N when idle)
+       OpsReleased uint64
+       // Number of deferred-release async ops garbage collected
+       OpsGarbageCollected uint64
+       // Number of in-progress alloc_object() cache ops
+       CacheopAllocationsinProgress uint64
+       // Number of in-progress lookup_object() cache ops
+       CacheopLookupObjectInProgress uint64
+       // Number of in-progress lookup_complete() cache ops
+       CacheopLookupCompleteInPorgress uint64
+       // Number of in-progress grab_object() cache ops
+       CacheopGrabObjectInProgress uint64
+       CacheopInvalidations        uint64
+       // Number of in-progress update_object() cache ops
+       CacheopUpdateObjectInProgress uint64
+       // Number of in-progress drop_object() cache ops
+       CacheopDropObjectInProgress uint64
+       // Number of in-progress put_object() cache ops
+       CacheopPutObjectInProgress uint64
+       // Number of in-progress attr_changed() cache ops
+       CacheopAttributeChangeInProgress uint64
+       // Number of in-progress sync_cache() cache ops
+       CacheopSyncCacheInProgress uint64
+       // Number of in-progress read_or_alloc_page() cache ops
+       CacheopReadOrAllocPageInProgress uint64
+       // Number of in-progress read_or_alloc_pages() cache ops
+       CacheopReadOrAllocPagesInProgress uint64
+       // Number of in-progress allocate_page() cache ops
+       CacheopAllocatePageInProgress uint64
+       // Number of in-progress allocate_pages() cache ops
+       CacheopAllocatePagesInProgress uint64
+       // Number of in-progress write_page() cache ops
+       CacheopWritePagesInProgress uint64
+       // Number of in-progress uncache_page() cache ops
+       CacheopUncachePagesInProgress uint64
+       // Number of in-progress dissociate_pages() cache ops
+       CacheopDissociatePagesInProgress uint64
+       // Number of object lookups/creations rejected due to lack of space
+       CacheevLookupsAndCreationsRejectedLackSpace uint64
+       // Number of stale objects deleted
+       CacheevStaleObjectsDeleted uint64
+       // Number of objects retired when relinquished
+       CacheevRetiredWhenReliquished uint64
+       // Number of objects culled
+       CacheevObjectsCulled uint64
+}
+
+// Fscacheinfo returns information about current fscache statistics.
+// See https://www.kernel.org/doc/Documentation/filesystems/caching/fscache.txt
+func (fs FS) Fscacheinfo() (Fscacheinfo, error) {
+       b, err := util.ReadFileNoStat(fs.proc.Path("fs/fscache/stats"))
+       if err != nil {
+               return Fscacheinfo{}, err
+       }
+
+       m, err := parseFscacheinfo(bytes.NewReader(b))
+       if err != nil {
+               return Fscacheinfo{}, fmt.Errorf("failed to parse Fscacheinfo: %v", err)
+       }
+
+       return *m, nil
+}
+
+func setFSCacheFields(fields []string, setFields ...*uint64) error {
+       var err error
+       if len(fields) < len(setFields) {
+               return fmt.Errorf("Insufficient number of fields, expected %v, got %v", len(setFields), len(fields))
+       }
+
+       for i := range setFields {
+               *setFields[i], err = strconv.ParseUint(strings.Split(fields[i], "=")[1], 0, 64)
+               if err != nil {
+                       return err
+               }
+       }
+       return nil
+}
+
+func parseFscacheinfo(r io.Reader) (*Fscacheinfo, error) {
+       var m Fscacheinfo
+       s := bufio.NewScanner(r)
+       for s.Scan() {
+               fields := strings.Fields(s.Text())
+               if len(fields) < 2 {
+                       return nil, fmt.Errorf("malformed Fscacheinfo line: %q", s.Text())
+               }
+
+               switch fields[0] {
+               case "Cookies:":
+                       err := setFSCacheFields(fields[1:], &m.IndexCookiesAllocated, &m.DataStorageCookiesAllocated,
+                               &m.SpecialCookiesAllocated)
+                       if err != nil {
+                               return &m, err
+                       }
+               case "Objects:":
+                       err := setFSCacheFields(fields[1:], &m.ObjectsAllocated, &m.ObjectAllocationsFailure,
+                               &m.ObjectsAvailable, &m.ObjectsDead)
+                       if err != nil {
+                               return &m, err
+                       }
+               case "ChkAux":
+                       err := setFSCacheFields(fields[2:], &m.ObjectsWithoutCoherencyCheck, &m.ObjectsWithCoherencyCheck,
+                               &m.ObjectsNeedCoherencyCheckUpdate, &m.ObjectsDeclaredObsolete)
+                       if err != nil {
+                               return &m, err
+                       }
+               case "Pages":
+                       err := setFSCacheFields(fields[2:], &m.PagesMarkedAsBeingCached, &m.UncachePagesRequestSeen)
+                       if err != nil {
+                               return &m, err
+                       }
+               case "Acquire:":
+                       err := setFSCacheFields(fields[1:], &m.AcquireCookiesRequestSeen, &m.AcquireRequestsWithNullParent,
+                               &m.AcquireRequestsRejectedNoCacheAvailable, &m.AcquireRequestsSucceeded, &m.AcquireRequestsRejectedDueToError,
+                               &m.AcquireRequestsFailedDueToEnomem)
+                       if err != nil {
+                               return &m, err
+                       }
+               case "Lookups:":
+                       err := setFSCacheFields(fields[1:], &m.LookupsNumber, &m.LookupsNegative, &m.LookupsPositive,
+                               &m.ObjectsCreatedByLookup, &m.LookupsTimedOutAndRequed)
+                       if err != nil {
+                               return &m, err
+                       }
+               case "Invals":
+                       err := setFSCacheFields(fields[2:], &m.InvalidationsNumber, &m.InvalidationsRunning)
+                       if err != nil {
+                               return &m, err
+                       }
+               case "Updates:":
+                       err := setFSCacheFields(fields[1:], &m.UpdateCookieRequestSeen, &m.UpdateRequestsWithNullParent,
+                               &m.UpdateRequestsRunning)
+                       if err != nil {
+                               return &m, err
+                       }
+               case "Relinqs:":
+                       err := setFSCacheFields(fields[1:], &m.RelinquishCookiesRequestSeen, &m.RelinquishCookiesWithNullParent,
+                               &m.RelinquishRequestsWaitingCompleteCreation, &m.RelinquishRetries)
+                       if err != nil {
+                               return &m, err
+                       }
+               case "AttrChg:":
+                       err := setFSCacheFields(fields[1:], &m.AttributeChangedRequestsSeen, &m.AttributeChangedRequestsQueued,
+                               &m.AttributeChangedRejectDueToEnobufs, &m.AttributeChangedFailedDueToEnomem, &m.AttributeChangedOps)
+                       if err != nil {
+                               return &m, err
+                       }
+               case "Allocs":
+                       if strings.Split(fields[2], "=")[0] == "n" {
+                               err := setFSCacheFields(fields[2:], &m.AllocationRequestsSeen, &m.AllocationOkRequests,
+                                       &m.AllocationWaitingOnLookup, &m.AllocationsRejectedDueToEnobufs, &m.AllocationsAbortedDueToErestartsys)
+                               if err != nil {
+                                       return &m, err
+                               }
+                       } else {
+                               err := setFSCacheFields(fields[2:], &m.AllocationOperationsSubmitted, &m.AllocationsWaitedForCPU,
+                                       &m.AllocationsAbortedDueToObjectDeath)
+                               if err != nil {
+                                       return &m, err
+                               }
+                       }
+               case "Retrvls:":
+                       if strings.Split(fields[1], "=")[0] == "n" {
+                               err := setFSCacheFields(fields[1:], &m.RetrievalsReadRequests, &m.RetrievalsOk, &m.RetrievalsWaitingLookupCompletion,
+                                       &m.RetrievalsReturnedEnodata, &m.RetrievalsRejectedDueToEnobufs, &m.RetrievalsAbortedDueToErestartsys,
+                                       &m.RetrievalsFailedDueToEnomem)
+                               if err != nil {
+                                       return &m, err
+                               }
+                       } else {
+                               err := setFSCacheFields(fields[1:], &m.RetrievalsRequests, &m.RetrievalsWaitingCPU, &m.RetrievalsAbortedDueToObjectDeath)
+                               if err != nil {
+                                       return &m, err
+                               }
+                       }
+               case "Stores":
+                       if strings.Split(fields[2], "=")[0] == "n" {
+                               err := setFSCacheFields(fields[2:], &m.StoreWriteRequests, &m.StoreSuccessfulRequests,
+                                       &m.StoreRequestsOnPendingStorage, &m.StoreRequestsRejectedDueToEnobufs, &m.StoreRequestsFailedDueToEnomem)
+                               if err != nil {
+                                       return &m, err
+                               }
+                       } else {
+                               err := setFSCacheFields(fields[2:], &m.StoreRequestsSubmitted, &m.StoreRequestsRunning,
+                                       &m.StorePagesWithRequestsProcessing, &m.StoreRequestsDeleted, &m.StoreRequestsOverStoreLimit)
+                               if err != nil {
+                                       return &m, err
+                               }
+                       }
+               case "VmScan":
+                       err := setFSCacheFields(fields[2:], &m.ReleaseRequestsAgainstPagesWithNoPendingStorage,
+                               &m.ReleaseRequestsAgainstPagesStoredByTimeLockGranted, &m.ReleaseRequestsIgnoredDueToInProgressStore,
+                               &m.PageStoresCancelledByReleaseRequests, &m.VmscanWaiting)
+                       if err != nil {
+                               return &m, err
+                       }
+               case "Ops":
+                       if strings.Split(fields[2], "=")[0] == "pend" {
+                               err := setFSCacheFields(fields[2:], &m.OpsPending, &m.OpsRunning, &m.OpsEnqueued, &m.OpsCancelled, &m.OpsRejected)
+                               if err != nil {
+                                       return &m, err
+                               }
+                       } else {
+                               err := setFSCacheFields(fields[2:], &m.OpsInitialised, &m.OpsDeferred, &m.OpsReleased, &m.OpsGarbageCollected)
+                               if err != nil {
+                                       return &m, err
+                               }
+                       }
+               case "CacheOp:":
+                       if strings.Split(fields[1], "=")[0] == "alo" {
+                               err := setFSCacheFields(fields[1:], &m.CacheopAllocationsinProgress, &m.CacheopLookupObjectInProgress,
+                                       &m.CacheopLookupCompleteInPorgress, &m.CacheopGrabObjectInProgress)
+                               if err != nil {
+                                       return &m, err
+                               }
+                       } else if strings.Split(fields[1], "=")[0] == "inv" {
+                               err := setFSCacheFields(fields[1:], &m.CacheopInvalidations, &m.CacheopUpdateObjectInProgress,
+                                       &m.CacheopDropObjectInProgress, &m.CacheopPutObjectInProgress, &m.CacheopAttributeChangeInProgress,
+                                       &m.CacheopSyncCacheInProgress)
+                               if err != nil {
+                                       return &m, err
+                               }
+                       } else {
+                               err := setFSCacheFields(fields[1:], &m.CacheopReadOrAllocPageInProgress, &m.CacheopReadOrAllocPagesInProgress,
+                                       &m.CacheopAllocatePageInProgress, &m.CacheopAllocatePagesInProgress, &m.CacheopWritePagesInProgress,
+                                       &m.CacheopUncachePagesInProgress, &m.CacheopDissociatePagesInProgress)
+                               if err != nil {
+                                       return &m, err
+                               }
+                       }
+               case "CacheEv:":
+                       err := setFSCacheFields(fields[1:], &m.CacheevLookupsAndCreationsRejectedLackSpace, &m.CacheevStaleObjectsDeleted,
+                               &m.CacheevRetiredWhenReliquished, &m.CacheevObjectsCulled)
+                       if err != nil {
+                               return &m, err
+                       }
+               }
+       }
+
+       return &m, nil
+}
index 755591d9a5e96731c1b8da6b0e22792c1c89f06d..22cb07a6bbb5f8a2cad05ffcb8bea8658014e332 100644 (file)
@@ -73,6 +73,15 @@ func ReadUintFromFile(path string) (uint64, error) {
        return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
 }
 
+// ReadIntFromFile reads a file and attempts to parse a int64 from it.
+func ReadIntFromFile(path string) (int64, error) {
+       data, err := ioutil.ReadFile(path)
+       if err != nil {
+               return 0, err
+       }
+       return strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64)
+}
+
 // ParseBool parses a string into a boolean pointer.
 func ParseBool(b string) *bool {
        var truth bool
diff --git a/vendor/github.com/prometheus/procfs/kernel_random.go b/vendor/github.com/prometheus/procfs/kernel_random.go
new file mode 100644 (file)
index 0000000..beefdf0
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright 2020 The Prometheus 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.
+
+// +build !windows
+
+package procfs
+
+import (
+       "os"
+
+       "github.com/prometheus/procfs/internal/util"
+)
+
+// KernelRandom contains information about to the kernel's random number generator.
+type KernelRandom struct {
+       // EntropyAvaliable gives the available entropy, in bits.
+       EntropyAvaliable *uint64
+       // PoolSize gives the size of the entropy pool, in bytes.
+       PoolSize *uint64
+       // URandomMinReseedSeconds is the number of seconds after which the DRNG will be reseeded.
+       URandomMinReseedSeconds *uint64
+       // WriteWakeupThreshold the number of bits of entropy below which we wake up processes
+       // that do a select(2) or poll(2) for write access to /dev/random.
+       WriteWakeupThreshold *uint64
+       // ReadWakeupThreshold is the number of bits of entropy required for waking up processes that sleep
+       // waiting for entropy from /dev/random.
+       ReadWakeupThreshold *uint64
+}
+
+// KernelRandom returns values from /proc/sys/kernel/random.
+func (fs FS) KernelRandom() (KernelRandom, error) {
+       random := KernelRandom{}
+
+       for file, p := range map[string]**uint64{
+               "entropy_avail":           &random.EntropyAvaliable,
+               "poolsize":                &random.PoolSize,
+               "urandom_min_reseed_secs": &random.URandomMinReseedSeconds,
+               "write_wakeup_threshold":  &random.WriteWakeupThreshold,
+               "read_wakeup_threshold":   &random.ReadWakeupThreshold,
+       } {
+               val, err := util.ReadUintFromFile(fs.proc.Path("sys", "kernel", "random", file))
+               if os.IsNotExist(err) {
+                       continue
+               }
+               if err != nil {
+                       return random, err
+               }
+               *p = &val
+       }
+
+       return random, nil
+}
index 2af3ada180453b51a1c474f23fff6b23ef30f7ce..3e9362a94d93053435954a5f1d0df1be0aaf069e 100644 (file)
@@ -52,7 +52,7 @@ type MDStat struct {
 func (fs FS) MDStat() ([]MDStat, error) {
        data, err := ioutil.ReadFile(fs.proc.Path("mdstat"))
        if err != nil {
-               return nil, fmt.Errorf("error parsing mdstat %s: %s", fs.proc.Path("mdstat"), err)
+               return nil, err
        }
        mdstat, err := parseMDStat(data)
        if err != nil {
index 947113610131324bc71ce9023954da55dfd51d4e..59f4d505583627982cbb85f031ec24180d517394 100644 (file)
@@ -77,7 +77,7 @@ func parseMountInfoString(mountString string) (*MountInfo, error) {
 
        mountInfo := strings.Split(mountString, " ")
        mountInfoLength := len(mountInfo)
-       if mountInfoLength < 11 {
+       if mountInfoLength < 10 {
                return nil, fmt.Errorf("couldn't find enough fields in mount string: %s", mountString)
        }
 
@@ -144,7 +144,7 @@ func mountOptionsParseOptionalFields(o []string) (map[string]string, error) {
        return optionalFields, nil
 }
 
-// Parses the mount options, superblock options.
+// mountOptionsParser parses the mount options, superblock options.
 func mountOptionsParser(mountOptions string) map[string]string {
        opts := make(map[string]string)
        options := strings.Split(mountOptions, ",")
@@ -161,7 +161,7 @@ func mountOptionsParser(mountOptions string) map[string]string {
        return opts
 }
 
-// Retrieves mountinfo information from `/proc/self/mountinfo`.
+// GetMounts retrieves mountinfo information from `/proc/self/mountinfo`.
 func GetMounts() ([]*MountInfo, error) {
        data, err := util.ReadFileNoStat("/proc/self/mountinfo")
        if err != nil {
@@ -170,7 +170,7 @@ func GetMounts() ([]*MountInfo, error) {
        return parseMountInfo(data)
 }
 
-// Retrieves mountinfo information from a processes' `/proc/<pid>/mountinfo`.
+// GetProcMounts retrieves mountinfo information from a processes' `/proc/<pid>/mountinfo`.
 func GetProcMounts(pid int) ([]*MountInfo, error) {
        data, err := util.ReadFileNoStat(fmt.Sprintf("/proc/%d/mountinfo", pid))
        if err != nil {
index 35b2ef3513f915f89f9a09764ff92a6c586e2088..861ced9da030410b4307e75f1659e93b61038746 100644 (file)
@@ -186,6 +186,8 @@ type NFSOperationStats struct {
        CumulativeTotalResponseMilliseconds uint64
        // Duration from when a request was enqueued to when it was completely handled.
        CumulativeTotalRequestMilliseconds uint64
+       // The count of operations that complete with tk_status < 0.  These statuses usually indicate error conditions.
+       Errors uint64
 }
 
 // A NFSTransportStats contains statistics for the NFS mount RPC requests and
@@ -494,8 +496,8 @@ func parseNFSEventsStats(ss []string) (*NFSEventsStats, error) {
 // line is reached.
 func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
        const (
-               // Number of expected fields in each per-operation statistics set
-               numFields = 9
+               // Minimum number of expected fields in each per-operation statistics set
+               minFields = 9
        )
 
        var ops []NFSOperationStats
@@ -508,12 +510,12 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
                        break
                }
 
-               if len(ss) != numFields {
+               if len(ss) < minFields {
                        return nil, fmt.Errorf("invalid NFS per-operations stats: %v", ss)
                }
 
                // Skip string operation name for integers
-               ns := make([]uint64, 0, numFields-1)
+               ns := make([]uint64, 0, minFields-1)
                for _, st := range ss[1:] {
                        n, err := strconv.ParseUint(st, 10, 64)
                        if err != nil {
@@ -523,7 +525,7 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
                        ns = append(ns, n)
                }
 
-               ops = append(ops, NFSOperationStats{
+               opStats := NFSOperationStats{
                        Operation:                           strings.TrimSuffix(ss[0], ":"),
                        Requests:                            ns[0],
                        Transmissions:                       ns[1],
@@ -533,7 +535,13 @@ func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
                        CumulativeQueueMilliseconds:         ns[5],
                        CumulativeTotalResponseMilliseconds: ns[6],
                        CumulativeTotalRequestMilliseconds:  ns[7],
-               })
+               }
+
+               if len(ns) > 8 {
+                       opStats.Errors = ns[8]
+               }
+
+               ops = append(ops, opStats)
        }
 
        return ops, s.Err()
index 1e27c83d50e51f783e8d3a8cb061dd7b942c6b1c..b637be98458f443502704b4b56a81169e0e8ad7c 100644 (file)
@@ -38,7 +38,7 @@ type ConntrackStatEntry struct {
        SearchRestart uint64
 }
 
-// Retrieves netfilter's conntrack statistics, split by CPU cores
+// ConntrackStat retrieves netfilter's conntrack statistics, split by CPU cores
 func (fs FS) ConntrackStat() ([]ConntrackStatEntry, error) {
        return readConntrackStat(fs.proc.Path("net", "stat", "nf_conntrack"))
 }
index 330e472c70fd2d6dcd5fb253e1326dc901f1e35f..9f97b6e5236a42ed4d595099d5552298fb6f3835 100644 (file)
@@ -134,6 +134,27 @@ func (p Proc) CmdLine() ([]string, error) {
        return strings.Split(string(bytes.TrimRight(data, string("\x00"))), string(byte(0))), nil
 }
 
+// Wchan returns the wchan (wait channel) of a process.
+func (p Proc) Wchan() (string, error) {
+       f, err := os.Open(p.path("wchan"))
+       if err != nil {
+               return "", err
+       }
+       defer f.Close()
+
+       data, err := ioutil.ReadAll(f)
+       if err != nil {
+               return "", err
+       }
+
+       wchan := string(data)
+       if wchan == "" || wchan == "0" {
+               return "", nil
+       }
+
+       return wchan, nil
+}
+
 // Comm returns the command name of a process.
 func (p Proc) Comm() (string, error) {
        data, err := util.ReadFileNoStat(p.path("comm"))
diff --git a/vendor/github.com/prometheus/procfs/proc_cgroup.go b/vendor/github.com/prometheus/procfs/proc_cgroup.go
new file mode 100644 (file)
index 0000000..4abd464
--- /dev/null
@@ -0,0 +1,98 @@
+// Copyright 2020 The Prometheus 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 procfs
+
+import (
+       "bufio"
+       "bytes"
+       "fmt"
+       "strconv"
+       "strings"
+
+       "github.com/prometheus/procfs/internal/util"
+)
+
+// Cgroup models one line from /proc/[pid]/cgroup. Each Cgroup struct describes the the placement of a PID inside a
+// specific control hierarchy. The kernel has two cgroup APIs, v1 and v2. v1 has one hierarchy per available resource
+// controller, while v2 has one unified hierarchy shared by all controllers. Regardless of v1 or v2, all hierarchies
+// contain all running processes, so the question answerable with a Cgroup struct is 'where is this process in
+// this hierarchy' (where==what path on the specific cgroupfs). By prefixing this path with the mount point of
+// *this specific* hierarchy, you can locate the relevant pseudo-files needed to read/set the data for this PID
+// in this hierarchy
+//
+// Also see http://man7.org/linux/man-pages/man7/cgroups.7.html
+type Cgroup struct {
+       // HierarchyID that can be matched to a named hierarchy using /proc/cgroups. Cgroups V2 only has one
+       // hierarchy, so HierarchyID is always 0. For cgroups v1 this is a unique ID number
+       HierarchyID int
+       // Controllers using this hierarchy of processes. Controllers are also known as subsystems. For
+       // Cgroups V2 this may be empty, as all active controllers use the same hierarchy
+       Controllers []string
+       // Path of this control group, relative to the mount point of the cgroupfs representing this specific
+       // hierarchy
+       Path string
+}
+
+// parseCgroupString parses each line of the /proc/[pid]/cgroup file
+// Line format is hierarchyID:[controller1,controller2]:path
+func parseCgroupString(cgroupStr string) (*Cgroup, error) {
+       var err error
+
+       fields := strings.Split(cgroupStr, ":")
+       if len(fields) < 3 {
+               return nil, fmt.Errorf("at least 3 fields required, found %d fields in cgroup string: %s", len(fields), cgroupStr)
+       }
+
+       cgroup := &Cgroup{
+               Path:        fields[2],
+               Controllers: nil,
+       }
+       cgroup.HierarchyID, err = strconv.Atoi(fields[0])
+       if err != nil {
+               return nil, fmt.Errorf("failed to parse hierarchy ID")
+       }
+       if fields[1] != "" {
+               ssNames := strings.Split(fields[1], ",")
+               cgroup.Controllers = append(cgroup.Controllers, ssNames...)
+       }
+       return cgroup, nil
+}
+
+// parseCgroups reads each line of the /proc/[pid]/cgroup file
+func parseCgroups(data []byte) ([]Cgroup, error) {
+       var cgroups []Cgroup
+       scanner := bufio.NewScanner(bytes.NewReader(data))
+       for scanner.Scan() {
+               mountString := scanner.Text()
+               parsedMounts, err := parseCgroupString(mountString)
+               if err != nil {
+                       return nil, err
+               }
+               cgroups = append(cgroups, *parsedMounts)
+       }
+
+       err := scanner.Err()
+       return cgroups, err
+}
+
+// Cgroups reads from /proc/<pid>/cgroups and returns a []*Cgroup struct locating this PID in each process
+// control hierarchy running on this system. On every system (v1 and v2), all hierarchies contain all processes,
+// so the len of the returned struct is equal to the number of active hierarchies on this system
+func (p Proc) Cgroups() ([]Cgroup, error) {
+       data, err := util.ReadFileNoStat(fmt.Sprintf("/proc/%d/cgroup", p.PID))
+       if err != nil {
+               return nil, err
+       }
+       return parseCgroups(data)
+}
index 0c9c402850c0f8adc2e0f55dda98693a56d5a758..a76ca7079194030248abdc376ac1694bc5cb26e0 100644 (file)
@@ -41,7 +41,7 @@ type ProcFDInfo struct {
        Flags string
        // Mount point ID
        MntID string
-       // List of inotify lines (structed) in the fdinfo file (kernel 3.8+ only)
+       // List of inotify lines (structured) in the fdinfo file (kernel 3.8+ only)
        InotifyInfos []InotifyInfo
 }
 
index 28d5c6eb1da89ecd0a9102c146d03e61608fdccf..1d7772d516a4a38820541794d2f625260ecf562b 100644 (file)
@@ -11,7 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// +build !windows
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package procfs
 
@@ -25,6 +25,7 @@ import (
        "golang.org/x/sys/unix"
 )
 
+// ProcMapPermissions contains permission settings read from /proc/[pid]/maps
 type ProcMapPermissions struct {
        // mapping has the [R]ead flag set
        Read bool
diff --git a/vendor/github.com/prometheus/procfs/proc_smaps.go b/vendor/github.com/prometheus/procfs/proc_smaps.go
new file mode 100644 (file)
index 0000000..a576a72
--- /dev/null
@@ -0,0 +1,165 @@
+// Copyright 2020 The Prometheus 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.
+
+// +build !windows
+
+package procfs
+
+import (
+       "bufio"
+       "errors"
+       "fmt"
+       "os"
+       "regexp"
+       "strconv"
+       "strings"
+
+       "github.com/prometheus/procfs/internal/util"
+)
+
+var (
+       // match the header line before each mapped zone in /proc/pid/smaps
+       procSMapsHeaderLine = regexp.MustCompile(`^[a-f0-9].*$`)
+)
+
+type ProcSMapsRollup struct {
+       // Amount of the mapping that is currently resident in RAM
+       Rss uint64
+       // Process's proportional share of this mapping
+       Pss uint64
+       // Size in bytes of clean shared pages
+       SharedClean uint64
+       // Size in bytes of dirty shared pages
+       SharedDirty uint64
+       // Size in bytes of clean private pages
+       PrivateClean uint64
+       // Size in bytes of dirty private pages
+       PrivateDirty uint64
+       // Amount of memory currently marked as referenced or accessed
+       Referenced uint64
+       // Amount of memory that does not belong to any file
+       Anonymous uint64
+       // Amount would-be-anonymous memory currently on swap
+       Swap uint64
+       // Process's proportional memory on swap
+       SwapPss uint64
+}
+
+// ProcSMapsRollup reads from /proc/[pid]/smaps_rollup to get summed memory information of the
+// process.
+//
+// If smaps_rollup does not exists (require kernel >= 4.15), the content of /proc/pid/smaps will
+// we read and summed.
+func (p Proc) ProcSMapsRollup() (ProcSMapsRollup, error) {
+       data, err := util.ReadFileNoStat(p.path("smaps_rollup"))
+       if err != nil && os.IsNotExist(err) {
+               return p.procSMapsRollupManual()
+       }
+       if err != nil {
+               return ProcSMapsRollup{}, err
+       }
+
+       lines := strings.Split(string(data), "\n")
+       smaps := ProcSMapsRollup{}
+
+       // skip first line which don't contains information we need
+       lines = lines[1:]
+       for _, line := range lines {
+               if line == "" {
+                       continue
+               }
+
+               if err := smaps.parseLine(line); err != nil {
+                       return ProcSMapsRollup{}, err
+               }
+       }
+
+       return smaps, nil
+}
+
+// Read /proc/pid/smaps and do the roll-up in Go code.
+func (p Proc) procSMapsRollupManual() (ProcSMapsRollup, error) {
+       file, err := os.Open(p.path("smaps"))
+       if err != nil {
+               return ProcSMapsRollup{}, err
+       }
+       defer file.Close()
+
+       smaps := ProcSMapsRollup{}
+       scan := bufio.NewScanner(file)
+
+       for scan.Scan() {
+               line := scan.Text()
+
+               if procSMapsHeaderLine.MatchString(line) {
+                       continue
+               }
+
+               if err := smaps.parseLine(line); err != nil {
+                       return ProcSMapsRollup{}, err
+               }
+       }
+
+       return smaps, nil
+}
+
+func (s *ProcSMapsRollup) parseLine(line string) error {
+       kv := strings.SplitN(line, ":", 2)
+       if len(kv) != 2 {
+               fmt.Println(line)
+               return errors.New("invalid net/dev line, missing colon")
+       }
+
+       k := kv[0]
+       if k == "VmFlags" {
+               return nil
+       }
+
+       v := strings.TrimSpace(kv[1])
+       v = strings.TrimRight(v, " kB")
+
+       vKBytes, err := strconv.ParseUint(v, 10, 64)
+       if err != nil {
+               return err
+       }
+       vBytes := vKBytes * 1024
+
+       s.addValue(k, v, vKBytes, vBytes)
+
+       return nil
+}
+
+func (s *ProcSMapsRollup) addValue(k string, vString string, vUint uint64, vUintBytes uint64) {
+       switch k {
+       case "Rss":
+               s.Rss += vUintBytes
+       case "Pss":
+               s.Pss += vUintBytes
+       case "Shared_Clean":
+               s.SharedClean += vUintBytes
+       case "Shared_Dirty":
+               s.SharedDirty += vUintBytes
+       case "Private_Clean":
+               s.PrivateClean += vUintBytes
+       case "Private_Dirty":
+               s.PrivateDirty += vUintBytes
+       case "Referenced":
+               s.Referenced += vUintBytes
+       case "Anonymous":
+               s.Anonymous += vUintBytes
+       case "Swap":
+               s.Swap += vUintBytes
+       case "SwapPss":
+               s.SwapPss += vUintBytes
+       }
+}
diff --git a/vendor/golang.org/x/crypto/bcrypt/base64.go b/vendor/golang.org/x/crypto/bcrypt/base64.go
new file mode 100644 (file)
index 0000000..fc31160
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2011 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 bcrypt
+
+import "encoding/base64"
+
+const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+
+var bcEncoding = base64.NewEncoding(alphabet)
+
+func base64Encode(src []byte) []byte {
+       n := bcEncoding.EncodedLen(len(src))
+       dst := make([]byte, n)
+       bcEncoding.Encode(dst, src)
+       for dst[n-1] == '=' {
+               n--
+       }
+       return dst[:n]
+}
+
+func base64Decode(src []byte) ([]byte, error) {
+       numOfEquals := 4 - (len(src) % 4)
+       for i := 0; i < numOfEquals; i++ {
+               src = append(src, '=')
+       }
+
+       dst := make([]byte, bcEncoding.DecodedLen(len(src)))
+       n, err := bcEncoding.Decode(dst, src)
+       if err != nil {
+               return nil, err
+       }
+       return dst[:n], nil
+}
diff --git a/vendor/golang.org/x/crypto/bcrypt/bcrypt.go b/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
new file mode 100644 (file)
index 0000000..aeb73f8
--- /dev/null
@@ -0,0 +1,295 @@
+// Copyright 2011 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 bcrypt implements Provos and Mazières's bcrypt adaptive hashing
+// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
+package bcrypt // import "golang.org/x/crypto/bcrypt"
+
+// The code is a port of Provos and Mazières's C implementation.
+import (
+       "crypto/rand"
+       "crypto/subtle"
+       "errors"
+       "fmt"
+       "io"
+       "strconv"
+
+       "golang.org/x/crypto/blowfish"
+)
+
+const (
+       MinCost     int = 4  // the minimum allowable cost as passed in to GenerateFromPassword
+       MaxCost     int = 31 // the maximum allowable cost as passed in to GenerateFromPassword
+       DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword
+)
+
+// The error returned from CompareHashAndPassword when a password and hash do
+// not match.
+var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")
+
+// The error returned from CompareHashAndPassword when a hash is too short to
+// be a bcrypt hash.
+var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")
+
+// The error returned from CompareHashAndPassword when a hash was created with
+// a bcrypt algorithm newer than this implementation.
+type HashVersionTooNewError byte
+
+func (hv HashVersionTooNewError) Error() string {
+       return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion)
+}
+
+// The error returned from CompareHashAndPassword when a hash starts with something other than '$'
+type InvalidHashPrefixError byte
+
+func (ih InvalidHashPrefixError) Error() string {
+       return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih))
+}
+
+type InvalidCostError int
+
+func (ic InvalidCostError) Error() string {
+       return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost))
+}
+
+const (
+       majorVersion       = '2'
+       minorVersion       = 'a'
+       maxSaltSize        = 16
+       maxCryptedHashSize = 23
+       encodedSaltSize    = 22
+       encodedHashSize    = 31
+       minHashSize        = 59
+)
+
+// magicCipherData is an IV for the 64 Blowfish encryption calls in
+// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
+var magicCipherData = []byte{
+       0x4f, 0x72, 0x70, 0x68,
+       0x65, 0x61, 0x6e, 0x42,
+       0x65, 0x68, 0x6f, 0x6c,
+       0x64, 0x65, 0x72, 0x53,
+       0x63, 0x72, 0x79, 0x44,
+       0x6f, 0x75, 0x62, 0x74,
+}
+
+type hashed struct {
+       hash  []byte
+       salt  []byte
+       cost  int // allowed range is MinCost to MaxCost
+       major byte
+       minor byte
+}
+
+// GenerateFromPassword returns the bcrypt hash of the password at the given
+// cost. If the cost given is less than MinCost, the cost will be set to
+// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
+// to compare the returned hashed password with its cleartext version.
+func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
+       p, err := newFromPassword(password, cost)
+       if err != nil {
+               return nil, err
+       }
+       return p.Hash(), nil
+}
+
+// CompareHashAndPassword compares a bcrypt hashed password with its possible
+// plaintext equivalent. Returns nil on success, or an error on failure.
+func CompareHashAndPassword(hashedPassword, password []byte) error {
+       p, err := newFromHash(hashedPassword)
+       if err != nil {
+               return err
+       }
+
+       otherHash, err := bcrypt(password, p.cost, p.salt)
+       if err != nil {
+               return err
+       }
+
+       otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
+       if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
+               return nil
+       }
+
+       return ErrMismatchedHashAndPassword
+}
+
+// Cost returns the hashing cost used to create the given hashed
+// password. When, in the future, the hashing cost of a password system needs
+// to be increased in order to adjust for greater computational power, this
+// function allows one to establish which passwords need to be updated.
+func Cost(hashedPassword []byte) (int, error) {
+       p, err := newFromHash(hashedPassword)
+       if err != nil {
+               return 0, err
+       }
+       return p.cost, nil
+}
+
+func newFromPassword(password []byte, cost int) (*hashed, error) {
+       if cost < MinCost {
+               cost = DefaultCost
+       }
+       p := new(hashed)
+       p.major = majorVersion
+       p.minor = minorVersion
+
+       err := checkCost(cost)
+       if err != nil {
+               return nil, err
+       }
+       p.cost = cost
+
+       unencodedSalt := make([]byte, maxSaltSize)
+       _, err = io.ReadFull(rand.Reader, unencodedSalt)
+       if err != nil {
+               return nil, err
+       }
+
+       p.salt = base64Encode(unencodedSalt)
+       hash, err := bcrypt(password, p.cost, p.salt)
+       if err != nil {
+               return nil, err
+       }
+       p.hash = hash
+       return p, err
+}
+
+func newFromHash(hashedSecret []byte) (*hashed, error) {
+       if len(hashedSecret) < minHashSize {
+               return nil, ErrHashTooShort
+       }
+       p := new(hashed)
+       n, err := p.decodeVersion(hashedSecret)
+       if err != nil {
+               return nil, err
+       }
+       hashedSecret = hashedSecret[n:]
+       n, err = p.decodeCost(hashedSecret)
+       if err != nil {
+               return nil, err
+       }
+       hashedSecret = hashedSecret[n:]
+
+       // The "+2" is here because we'll have to append at most 2 '=' to the salt
+       // when base64 decoding it in expensiveBlowfishSetup().
+       p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
+       copy(p.salt, hashedSecret[:encodedSaltSize])
+
+       hashedSecret = hashedSecret[encodedSaltSize:]
+       p.hash = make([]byte, len(hashedSecret))
+       copy(p.hash, hashedSecret)
+
+       return p, nil
+}
+
+func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
+       cipherData := make([]byte, len(magicCipherData))
+       copy(cipherData, magicCipherData)
+
+       c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
+       if err != nil {
+               return nil, err
+       }
+
+       for i := 0; i < 24; i += 8 {
+               for j := 0; j < 64; j++ {
+                       c.Encrypt(cipherData[i:i+8], cipherData[i:i+8])
+               }
+       }
+
+       // Bug compatibility with C bcrypt implementations. We only encode 23 of
+       // the 24 bytes encrypted.
+       hsh := base64Encode(cipherData[:maxCryptedHashSize])
+       return hsh, nil
+}
+
+func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
+       csalt, err := base64Decode(salt)
+       if err != nil {
+               return nil, err
+       }
+
+       // Bug compatibility with C bcrypt implementations. They use the trailing
+       // NULL in the key string during expansion.
+       // We copy the key to prevent changing the underlying array.
+       ckey := append(key[:len(key):len(key)], 0)
+
+       c, err := blowfish.NewSaltedCipher(ckey, csalt)
+       if err != nil {
+               return nil, err
+       }
+
+       var i, rounds uint64
+       rounds = 1 << cost
+       for i = 0; i < rounds; i++ {
+               blowfish.ExpandKey(ckey, c)
+               blowfish.ExpandKey(csalt, c)
+       }
+
+       return c, nil
+}
+
+func (p *hashed) Hash() []byte {
+       arr := make([]byte, 60)
+       arr[0] = '$'
+       arr[1] = p.major
+       n := 2
+       if p.minor != 0 {
+               arr[2] = p.minor
+               n = 3
+       }
+       arr[n] = '$'
+       n++
+       copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
+       n += 2
+       arr[n] = '$'
+       n++
+       copy(arr[n:], p.salt)
+       n += encodedSaltSize
+       copy(arr[n:], p.hash)
+       n += encodedHashSize
+       return arr[:n]
+}
+
+func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
+       if sbytes[0] != '$' {
+               return -1, InvalidHashPrefixError(sbytes[0])
+       }
+       if sbytes[1] > majorVersion {
+               return -1, HashVersionTooNewError(sbytes[1])
+       }
+       p.major = sbytes[1]
+       n := 3
+       if sbytes[2] != '$' {
+               p.minor = sbytes[2]
+               n++
+       }
+       return n, nil
+}
+
+// sbytes should begin where decodeVersion left off.
+func (p *hashed) decodeCost(sbytes []byte) (int, error) {
+       cost, err := strconv.Atoi(string(sbytes[0:2]))
+       if err != nil {
+               return -1, err
+       }
+       err = checkCost(cost)
+       if err != nil {
+               return -1, err
+       }
+       p.cost = cost
+       return 3, nil
+}
+
+func (p *hashed) String() string {
+       return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor)
+}
+
+func checkCost(cost int) error {
+       if cost < MinCost || cost > MaxCost {
+               return InvalidCostError(cost)
+       }
+       return nil
+}
diff --git a/vendor/golang.org/x/crypto/blowfish/block.go b/vendor/golang.org/x/crypto/blowfish/block.go
new file mode 100644 (file)
index 0000000..9d80f19
--- /dev/null
@@ -0,0 +1,159 @@
+// Copyright 2010 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 blowfish
+
+// getNextWord returns the next big-endian uint32 value from the byte slice
+// at the given position in a circular manner, updating the position.
+func getNextWord(b []byte, pos *int) uint32 {
+       var w uint32
+       j := *pos
+       for i := 0; i < 4; i++ {
+               w = w<<8 | uint32(b[j])
+               j++
+               if j >= len(b) {
+                       j = 0
+               }
+       }
+       *pos = j
+       return w
+}
+
+// ExpandKey performs a key expansion on the given *Cipher. Specifically, it
+// performs the Blowfish algorithm's key schedule which sets up the *Cipher's
+// pi and substitution tables for calls to Encrypt. This is used, primarily,
+// by the bcrypt package to reuse the Blowfish key schedule during its
+// set up. It's unlikely that you need to use this directly.
+func ExpandKey(key []byte, c *Cipher) {
+       j := 0
+       for i := 0; i < 18; i++ {
+               // Using inlined getNextWord for performance.
+               var d uint32
+               for k := 0; k < 4; k++ {
+                       d = d<<8 | uint32(key[j])
+                       j++
+                       if j >= len(key) {
+                               j = 0
+                       }
+               }
+               c.p[i] ^= d
+       }
+
+       var l, r uint32
+       for i := 0; i < 18; i += 2 {
+               l, r = encryptBlock(l, r, c)
+               c.p[i], c.p[i+1] = l, r
+       }
+
+       for i := 0; i < 256; i += 2 {
+               l, r = encryptBlock(l, r, c)
+               c.s0[i], c.s0[i+1] = l, r
+       }
+       for i := 0; i < 256; i += 2 {
+               l, r = encryptBlock(l, r, c)
+               c.s1[i], c.s1[i+1] = l, r
+       }
+       for i := 0; i < 256; i += 2 {
+               l, r = encryptBlock(l, r, c)
+               c.s2[i], c.s2[i+1] = l, r
+       }
+       for i := 0; i < 256; i += 2 {
+               l, r = encryptBlock(l, r, c)
+               c.s3[i], c.s3[i+1] = l, r
+       }
+}
+
+// This is similar to ExpandKey, but folds the salt during the key
+// schedule. While ExpandKey is essentially expandKeyWithSalt with an all-zero
+// salt passed in, reusing ExpandKey turns out to be a place of inefficiency
+// and specializing it here is useful.
+func expandKeyWithSalt(key []byte, salt []byte, c *Cipher) {
+       j := 0
+       for i := 0; i < 18; i++ {
+               c.p[i] ^= getNextWord(key, &j)
+       }
+
+       j = 0
+       var l, r uint32
+       for i := 0; i < 18; i += 2 {
+               l ^= getNextWord(salt, &j)
+               r ^= getNextWord(salt, &j)
+               l, r = encryptBlock(l, r, c)
+               c.p[i], c.p[i+1] = l, r
+       }
+
+       for i := 0; i < 256; i += 2 {
+               l ^= getNextWord(salt, &j)
+               r ^= getNextWord(salt, &j)
+               l, r = encryptBlock(l, r, c)
+               c.s0[i], c.s0[i+1] = l, r
+       }
+
+       for i := 0; i < 256; i += 2 {
+               l ^= getNextWord(salt, &j)
+               r ^= getNextWord(salt, &j)
+               l, r = encryptBlock(l, r, c)
+               c.s1[i], c.s1[i+1] = l, r
+       }
+
+       for i := 0; i < 256; i += 2 {
+               l ^= getNextWord(salt, &j)
+               r ^= getNextWord(salt, &j)
+               l, r = encryptBlock(l, r, c)
+               c.s2[i], c.s2[i+1] = l, r
+       }
+
+       for i := 0; i < 256; i += 2 {
+               l ^= getNextWord(salt, &j)
+               r ^= getNextWord(salt, &j)
+               l, r = encryptBlock(l, r, c)
+               c.s3[i], c.s3[i+1] = l, r
+       }
+}
+
+func encryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
+       xl, xr := l, r
+       xl ^= c.p[0]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[1]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[2]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[3]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[4]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[5]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[6]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[7]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[8]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[9]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[10]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[11]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[12]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[13]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[14]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[15]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[16]
+       xr ^= c.p[17]
+       return xr, xl
+}
+
+func decryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
+       xl, xr := l, r
+       xl ^= c.p[17]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[16]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[15]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[14]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[13]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[12]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[11]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[10]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[9]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[8]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[7]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[6]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[5]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[4]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[3]
+       xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[2]
+       xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[1]
+       xr ^= c.p[0]
+       return xr, xl
+}
diff --git a/vendor/golang.org/x/crypto/blowfish/cipher.go b/vendor/golang.org/x/crypto/blowfish/cipher.go
new file mode 100644 (file)
index 0000000..213bf20
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright 2010 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 blowfish implements Bruce Schneier's Blowfish encryption algorithm.
+//
+// Blowfish is a legacy cipher and its short block size makes it vulnerable to
+// birthday bound attacks (see https://sweet32.info). It should only be used
+// where compatibility with legacy systems, not security, is the goal.
+//
+// Deprecated: any new system should use AES (from crypto/aes, if necessary in
+// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
+// golang.org/x/crypto/chacha20poly1305).
+package blowfish // import "golang.org/x/crypto/blowfish"
+
+// The code is a port of Bruce Schneier's C implementation.
+// See https://www.schneier.com/blowfish.html.
+
+import "strconv"
+
+// The Blowfish block size in bytes.
+const BlockSize = 8
+
+// A Cipher is an instance of Blowfish encryption using a particular key.
+type Cipher struct {
+       p              [18]uint32
+       s0, s1, s2, s3 [256]uint32
+}
+
+type KeySizeError int
+
+func (k KeySizeError) Error() string {
+       return "crypto/blowfish: invalid key size " + strconv.Itoa(int(k))
+}
+
+// NewCipher creates and returns a Cipher.
+// The key argument should be the Blowfish key, from 1 to 56 bytes.
+func NewCipher(key []byte) (*Cipher, error) {
+       var result Cipher
+       if k := len(key); k < 1 || k > 56 {
+               return nil, KeySizeError(k)
+       }
+       initCipher(&result)
+       ExpandKey(key, &result)
+       return &result, nil
+}
+
+// NewSaltedCipher creates a returns a Cipher that folds a salt into its key
+// schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is
+// sufficient and desirable. For bcrypt compatibility, the key can be over 56
+// bytes.
+func NewSaltedCipher(key, salt []byte) (*Cipher, error) {
+       if len(salt) == 0 {
+               return NewCipher(key)
+       }
+       var result Cipher
+       if k := len(key); k < 1 {
+               return nil, KeySizeError(k)
+       }
+       initCipher(&result)
+       expandKeyWithSalt(key, salt, &result)
+       return &result, nil
+}
+
+// BlockSize returns the Blowfish block size, 8 bytes.
+// It is necessary to satisfy the Block interface in the
+// package "crypto/cipher".
+func (c *Cipher) BlockSize() int { return BlockSize }
+
+// Encrypt encrypts the 8-byte buffer src using the key k
+// and stores the result in dst.
+// Note that for amounts of data larger than a block,
+// it is not safe to just call Encrypt on successive blocks;
+// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
+func (c *Cipher) Encrypt(dst, src []byte) {
+       l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
+       r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
+       l, r = encryptBlock(l, r, c)
+       dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
+       dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
+}
+
+// Decrypt decrypts the 8-byte buffer src using the key k
+// and stores the result in dst.
+func (c *Cipher) Decrypt(dst, src []byte) {
+       l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
+       r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
+       l, r = decryptBlock(l, r, c)
+       dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
+       dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
+}
+
+func initCipher(c *Cipher) {
+       copy(c.p[0:], p[0:])
+       copy(c.s0[0:], s0[0:])
+       copy(c.s1[0:], s1[0:])
+       copy(c.s2[0:], s2[0:])
+       copy(c.s3[0:], s3[0:])
+}
diff --git a/vendor/golang.org/x/crypto/blowfish/const.go b/vendor/golang.org/x/crypto/blowfish/const.go
new file mode 100644 (file)
index 0000000..d040775
--- /dev/null
@@ -0,0 +1,199 @@
+// Copyright 2010 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.
+
+// The startup permutation array and substitution boxes.
+// They are the hexadecimal digits of PI; see:
+// https://www.schneier.com/code/constants.txt.
+
+package blowfish
+
+var s0 = [256]uint32{
+       0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
+       0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+       0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
+       0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+       0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
+       0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+       0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
+       0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+       0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
+       0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+       0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
+       0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+       0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
+       0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+       0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
+       0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+       0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
+       0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+       0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
+       0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+       0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
+       0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+       0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
+       0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+       0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
+       0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+       0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
+       0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+       0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
+       0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+       0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
+       0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+       0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
+       0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+       0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
+       0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+       0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
+       0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+       0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
+       0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+       0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
+       0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+       0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
+}
+
+var s1 = [256]uint32{
+       0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d,
+       0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+       0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,
+       0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+       0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9,
+       0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+       0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d,
+       0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+       0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
+       0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+       0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908,
+       0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+       0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124,
+       0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+       0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,
+       0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+       0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b,
+       0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+       0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
+       0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+       0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,
+       0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+       0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5,
+       0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+       0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96,
+       0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+       0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,
+       0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+       0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
+       0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+       0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054,
+       0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+       0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,
+       0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+       0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646,
+       0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+       0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea,
+       0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+       0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
+       0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+       0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd,
+       0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+       0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
+}
+
+var s2 = [256]uint32{
+       0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7,
+       0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+       0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
+       0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+       0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4,
+       0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+       0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec,
+       0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+       0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,
+       0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+       0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58,
+       0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+       0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
+       0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+       0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,
+       0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+       0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99,
+       0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+       0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74,
+       0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+       0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,
+       0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+       0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
+       0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+       0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa,
+       0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+       0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,
+       0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+       0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24,
+       0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+       0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84,
+       0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+       0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
+       0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+       0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe,
+       0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+       0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0,
+       0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+       0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,
+       0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+       0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8,
+       0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+       0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
+}
+
+var s3 = [256]uint32{
+       0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
+       0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+       0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
+       0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+       0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
+       0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+       0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
+       0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+       0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
+       0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+       0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
+       0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+       0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
+       0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+       0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
+       0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+       0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
+       0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+       0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
+       0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+       0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
+       0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+       0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
+       0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+       0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
+       0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+       0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
+       0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+       0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
+       0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+       0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
+       0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+       0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
+       0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+       0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
+       0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+       0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
+       0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+       0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
+       0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+       0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
+       0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+       0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
+}
+
+var p = [18]uint32{
+       0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
+       0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+       0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b,
+}
diff --git a/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go b/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go
new file mode 100644 (file)
index 0000000..e07899b
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package unsafeheader contains header declarations for the Go runtime's
+// slice and string implementations.
+//
+// This package allows x/sys to use types equivalent to
+// reflect.SliceHeader and reflect.StringHeader without introducing
+// a dependency on the (relatively heavy) "reflect" package.
+package unsafeheader
+
+import (
+       "unsafe"
+)
+
+// Slice is the runtime representation of a slice.
+// It cannot be used safely or portably and its representation may change in a later release.
+type Slice struct {
+       Data unsafe.Pointer
+       Len  int
+       Cap  int
+}
+
+// String is the runtime representation of a string.
+// It cannot be used safely or portably and its representation may change in a later release.
+type String struct {
+       Data unsafe.Pointer
+       Len  int
+}
index ab09aafcf9061d179481073d6dec708b3f0a734d..08f8230d6d20277e5ccef1e0fe151fd3add92068 100644 (file)
@@ -187,6 +187,7 @@ struct ltchars {
 #include <sys/select.h>
 #include <sys/signalfd.h>
 #include <sys/socket.h>
+#include <sys/timerfd.h>
 #include <sys/uio.h>
 #include <sys/xattr.h>
 #include <linux/bpf.h>
@@ -480,7 +481,7 @@ ccflags="$@"
                $2 ~ /^(MS|MNT|UMOUNT)_/ ||
                $2 ~ /^NS_GET_/ ||
                $2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
-               $2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT)_/ ||
+               $2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|TFD)_/ ||
                $2 ~ /^KEXEC_/ ||
                $2 ~ /^LINUX_REBOOT_CMD_/ ||
                $2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
@@ -508,7 +509,7 @@ ccflags="$@"
                $2 ~ /^CAP_/ ||
                $2 ~ /^ALG_/ ||
                $2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE)/ ||
-               $2 ~ /^FS_IOC_.*(ENCRYPTION|VERITY|GETFLAGS)/ ||
+               $2 ~ /^FS_IOC_.*(ENCRYPTION|VERITY|[GS]ETFLAGS)/ ||
                $2 ~ /^FS_VERITY_/ ||
                $2 ~ /^FSCRYPT_/ ||
                $2 ~ /^GRND_/ ||
index f911617be95efca21db0781e065ed665464bb590..dc0befee37eb29947e6ae64728ad026ddc6887a0 100644 (file)
@@ -6,7 +6,11 @@
 
 package unix
 
-import "unsafe"
+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)
@@ -71,6 +75,7 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
                        cnt++
                        continue
                }
+
                reclen := int(entry.Reclen)
                if reclen > len(buf) {
                        // Not enough room. Return for now.
@@ -79,13 +84,15 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
                        // restarting is O(n^2) in the length of the directory. Oh well.
                        break
                }
+
                // Copy entry into return buffer.
-               s := struct {
-                       ptr unsafe.Pointer
-                       siz int
-                       cap int
-               }{ptr: unsafe.Pointer(&entry), siz: reclen, cap: reclen}
-               copy(buf, *(*[]byte)(unsafe.Pointer(&s)))
+               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++
index 9a5a6ee54456f933c031ce2e0b37c0910e3bf20e..0cf31acf02c792a7a54e147d0d052c33d70e8f53 100644 (file)
@@ -423,6 +423,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
 //sysnb        Getrlimit(which int, lim *Rlimit) (err error)
 //sysnb        Getrusage(who int, rusage *Rusage) (err error)
 //sysnb        Getsid(pid int) (sid int, err error)
+//sysnb        Gettimeofday(tp *Timeval) (err error)
 //sysnb        Getuid() (uid int)
 //sysnb        Issetugid() (tainted bool)
 //sys  Kqueue() (fd int, err error)
index 707ba4f59a236737bde43db3d8f60c06160acafc..2724e3a5128bbe7f4c38bf4cb484bc1692a3097c 100644 (file)
@@ -20,17 +20,6 @@ func setTimeval(sec, usec int64) Timeval {
        return Timeval{Sec: int32(sec), Usec: int32(usec)}
 }
 
-//sysnb        gettimeofday(tp *Timeval) (sec int32, usec int32, err error)
-func Gettimeofday(tv *Timeval) (err error) {
-       // The tv passed to gettimeofday must be non-nil
-       // but is otherwise unused. The answers come back
-       // in the two registers.
-       sec, usec, err := gettimeofday(tv)
-       tv.Sec = int32(sec)
-       tv.Usec = int32(usec)
-       return err
-}
-
 func SetKevent(k *Kevent_t, fd, mode, flags int) {
        k.Ident = uint32(fd)
        k.Filter = int16(mode)
index fdbfb5911ace1c3c66161cc02ff3d1c57c15fe5b..ce2e0d2497357d284930c397f43b1e051a06311b 100644 (file)
@@ -20,17 +20,6 @@ func setTimeval(sec, usec int64) Timeval {
        return Timeval{Sec: sec, Usec: int32(usec)}
 }
 
-//sysnb        gettimeofday(tp *Timeval) (sec int64, usec int32, err error)
-func Gettimeofday(tv *Timeval) (err error) {
-       // The tv passed to gettimeofday must be non-nil
-       // but is otherwise unused. The answers come back
-       // in the two registers.
-       sec, usec, err := gettimeofday(tv)
-       tv.Sec = sec
-       tv.Usec = usec
-       return err
-}
-
 func SetKevent(k *Kevent_t, fd, mode, flags int) {
        k.Ident = uint64(fd)
        k.Filter = int16(mode)
index f8bc4cfb1fafecffa81b81e4272a831d7c8a0075..fc17a3f232eb9c0167df75c46ed558802429bd4a 100644 (file)
@@ -20,17 +20,6 @@ func setTimeval(sec, usec int64) Timeval {
        return Timeval{Sec: int32(sec), Usec: int32(usec)}
 }
 
-//sysnb        gettimeofday(tp *Timeval) (sec int32, usec int32, err error)
-func Gettimeofday(tv *Timeval) (err error) {
-       // The tv passed to gettimeofday must be non-nil
-       // but is otherwise unused. The answers come back
-       // in the two registers.
-       sec, usec, err := gettimeofday(tv)
-       tv.Sec = int32(sec)
-       tv.Usec = int32(usec)
-       return err
-}
-
 func SetKevent(k *Kevent_t, fd, mode, flags int) {
        k.Ident = uint32(fd)
        k.Filter = int16(mode)
index 5ede3ac316abb373595f89304eabd60dd1f296cb..1e91ddf3257c9aa5182596c95b13ac31a56aa5d9 100644 (file)
@@ -22,17 +22,6 @@ func setTimeval(sec, usec int64) Timeval {
        return Timeval{Sec: sec, Usec: int32(usec)}
 }
 
-//sysnb        gettimeofday(tp *Timeval) (sec int64, usec int32, err error)
-func Gettimeofday(tv *Timeval) (err error) {
-       // The tv passed to gettimeofday must be non-nil
-       // but is otherwise unused. The answers come back
-       // in the two registers.
-       sec, usec, err := gettimeofday(tv)
-       tv.Sec = sec
-       tv.Usec = usec
-       return err
-}
-
 func SetKevent(k *Kevent_t, fd, mode, flags int) {
        k.Ident = uint64(fd)
        k.Filter = int16(mode)
index bbe1abbcee12373a7fdf9d9d3ab3574c80d93346..e50e4cb276c8608783ab77efb3a6519055c0098a 100644 (file)
@@ -97,6 +97,12 @@ func IoctlSetRTCTime(fd int, value *RTCTime) error {
        return err
 }
 
+func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error {
+       err := ioctl(fd, RTC_WKALM_SET, uintptr(unsafe.Pointer(value)))
+       runtime.KeepAlive(value)
+       return err
+}
+
 func IoctlGetUint32(fd int, req uint) (uint32, error) {
        var value uint32
        err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
@@ -109,6 +115,12 @@ func IoctlGetRTCTime(fd int) (*RTCTime, error) {
        return &value, err
 }
 
+func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) {
+       var value RTCWkAlrm
+       err := ioctl(fd, RTC_WKALM_RD, uintptr(unsafe.Pointer(&value)))
+       return &value, err
+}
+
 //sys  Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
 
 func Link(oldpath string, newpath string) (err error) {
@@ -1633,6 +1645,15 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
 //sys  CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
 //sys  DeleteModule(name string, flags int) (err error)
 //sys  Dup(oldfd int) (fd int, err error)
+
+func Dup2(oldfd, newfd int) error {
+       // Android O and newer blocks dup2; riscv and arm64 don't implement dup2.
+       if runtime.GOOS == "android" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "arm64" {
+               return Dup3(oldfd, newfd, 0)
+       }
+       return dup2(oldfd, newfd)
+}
+
 //sys  Dup3(oldfd int, newfd int, flags int) (err error)
 //sysnb        EpollCreate1(flag int) (fd int, err error)
 //sysnb        EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
@@ -1757,6 +1778,9 @@ func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
 //sys  Syncfs(fd int) (err error)
 //sysnb        Sysinfo(info *Sysinfo_t) (err error)
 //sys  Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
+//sysnb TimerfdCreate(clockid int, flags int) (fd int, err error)
+//sysnb TimerfdGettime(fd int, currValue *ItimerSpec) (err error)
+//sysnb TimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error)
 //sysnb        Tgkill(tgid int, tid int, sig syscall.Signal) (err error)
 //sysnb        Times(tms *Tms) (ticks uintptr, err error)
 //sysnb        Umask(mask int) (oldmask int)
@@ -1926,6 +1950,20 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
        return int(n), nil
 }
 
+func isGroupMember(gid int) bool {
+       groups, err := Getgroups()
+       if err != nil {
+               return false
+       }
+
+       for _, g := range groups {
+               if g == gid {
+                       return true
+               }
+       }
+       return false
+}
+
 //sys  faccessat(dirfd int, path string, mode uint32) (err error)
 
 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
@@ -1983,7 +2021,7 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
                        gid = Getgid()
                }
 
-               if uint32(gid) == st.Gid {
+               if uint32(gid) == st.Gid || isGroupMember(gid) {
                        fmode = (st.Mode >> 3) & 7
                } else {
                        fmode = st.Mode & 7
@@ -2178,7 +2216,6 @@ func Klogset(typ int, arg int) (err error) {
 // TimerGetoverrun
 // TimerGettime
 // TimerSettime
-// Timerfd
 // Tkill (obsolete)
 // Tuxcall
 // Umount2
index a8374b67cf848732279cb8046104a19d8c0072cf..048d18e3c810edc502c0d71ccfd2461bf1b4016d 100644 (file)
@@ -49,7 +49,7 @@ func Pipe2(p []int, flags int) (err error) {
 
 // 64-bit file system and 32-bit uid calls
 // (386 default is 32-bit file system and 16-bit uid).
-//sys  Dup2(oldfd int, newfd int) (err error)
+//sys  dup2(oldfd int, newfd int) (err error)
 //sysnb        EpollCreate(size int) (fd int, err error)
 //sys  EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
 //sys  Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64
index 8ed1d546f0bf4db5040aa243117ff3fcfe2c9acd..72efe86ed4ffc3a4c30170ccc31760ecfcf6d3cb 100644 (file)
@@ -6,7 +6,7 @@
 
 package unix
 
-//sys  Dup2(oldfd int, newfd int) (err error)
+//sys  dup2(oldfd int, newfd int) (err error)
 //sysnb        EpollCreate(size int) (fd int, err error)
 //sys  EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
 //sys  Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
index 99ae6137332bbe4367d70dd4360df79fa5e4b4c0..e1913e2c93469c4467cdfa282d5ce9715905f057 100644 (file)
@@ -80,7 +80,7 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
 
 // 64-bit file system and 32-bit uid calls
 // (16-bit uid calls are not always supported in newer kernels)
-//sys  Dup2(oldfd int, newfd int) (err error)
+//sys  dup2(oldfd int, newfd int) (err error)
 //sysnb        EpollCreate(size int) (fd int, err error)
 //sys  EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
 //sys  Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
index 807a0b20c3fa42b96a2cf939958ace09494c6265..c6de6b91345e17209481bacbde10d5ac18b9be1a 100644 (file)
@@ -25,7 +25,7 @@ func EpollCreate(size int) (fd int, err error) {
 //sysnb        Getegid() (egid int)
 //sysnb        Geteuid() (euid int)
 //sysnb        Getgid() (gid int)
-//sysnb        Getrlimit(resource int, rlim *Rlimit) (err error)
+//sysnb        getrlimit(resource int, rlim *Rlimit) (err error)
 //sysnb        Getuid() (uid int)
 //sys  Listen(s int, n int) (err error)
 //sys  Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
@@ -47,7 +47,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
 //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  Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
@@ -168,6 +168,24 @@ func Pipe2(p []int, flags int) (err error) {
        return
 }
 
+// Getrlimit prefers the prlimit64 system call. See issue 38604.
+func Getrlimit(resource int, rlim *Rlimit) error {
+       err := prlimit(0, resource, nil, rlim)
+       if err != ENOSYS {
+               return err
+       }
+       return getrlimit(resource, rlim)
+}
+
+// Setrlimit prefers the prlimit64 system call. See issue 38604.
+func Setrlimit(resource int, rlim *Rlimit) error {
+       err := prlimit(0, resource, rlim, nil)
+       if err != ENOSYS {
+               return err
+       }
+       return setrlimit(resource, rlim)
+}
+
 func (r *PtraceRegs) PC() uint64 { return r.Pc }
 
 func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc }
@@ -192,9 +210,9 @@ func InotifyInit() (fd int, err error) {
        return InotifyInit1(0)
 }
 
-func Dup2(oldfd int, newfd int) (err error) {
-       return Dup3(oldfd, newfd, 0)
-}
+// dup2 exists because func Dup3 in syscall_linux.go references
+// it in an unreachable path. dup2 isn't available on arm64.
+func dup2(oldfd int, newfd int) error
 
 func Pause() error {
        _, err := ppoll(nil, 0, nil, nil)
index af77e6e25eb74eba6e199d032090d2369c22b153..f0287476cd5d0b3d53203b6c49088c0153dc335e 100644 (file)
@@ -7,7 +7,7 @@
 
 package unix
 
-//sys  Dup2(oldfd int, newfd int) (err error)
+//sys  dup2(oldfd int, newfd int) (err error)
 //sysnb        EpollCreate(size int) (fd int, err error)
 //sys  EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
 //sys  Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
index e286c6ba31783cf9964b7526fd9c6273ab1c4b6c..c11328111d14dca9c0d83399825a67338b5b36fe 100644 (file)
@@ -14,7 +14,7 @@ import (
 
 func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
 
-//sys  Dup2(oldfd int, newfd int) (err error)
+//sys  dup2(oldfd int, newfd int) (err error)
 //sysnb        EpollCreate(size int) (fd int, err error)
 //sys  EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
 //sys  Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
index ca0345aabf28042640873b9585f50c9268c1b244..349374409ba194f5ba586e3601e6bf382947e4fa 100644 (file)
@@ -7,7 +7,7 @@
 
 package unix
 
-//sys  Dup2(oldfd int, newfd int) (err error)
+//sys  dup2(oldfd int, newfd int) (err error)
 //sysnb        EpollCreate(size int) (fd int, err error)
 //sys  EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
 //sys  Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
index abdabbac3f4a83f30c7a854ce696b967e0dcd89a..b0b1505565b3bcc835291497043b2e26b67b5b7d 100644 (file)
@@ -191,10 +191,6 @@ func InotifyInit() (fd int, err error) {
        return InotifyInit1(0)
 }
 
-func Dup2(oldfd int, newfd int) (err error) {
-       return Dup3(oldfd, newfd, 0)
-}
-
 func Pause() error {
        _, err := ppoll(nil, 0, nil, nil)
        return err
@@ -228,3 +224,7 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error
        }
        return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
 }
+
+// dup2 exists because func Dup3 in syscall_linux.go references
+// it in an unreachable path. dup2 isn't available on arm64.
+func dup2(oldfd int, newfd int) error
index 533e9305e7db68ed12fc742eb05b501989aea1ec..2363f749913b8143f3b7337a4fbe1f69108a84a3 100644 (file)
@@ -10,7 +10,7 @@ import (
        "unsafe"
 )
 
-//sys  Dup2(oldfd int, newfd int) (err error)
+//sys  dup2(oldfd int, newfd int) (err error)
 //sysnb        EpollCreate(size int) (fd int, err error)
 //sys  EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
 //sys  Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
index d890a227bf090a7f0ddbf71f421e9e39adc42a66..d389f1518faf0358ced16527de5d8cbac4560072 100644 (file)
@@ -8,7 +8,7 @@ package unix
 
 //sys  EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
 //sys  Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
-//sys  Dup2(oldfd int, newfd int) (err error)
+//sys  dup2(oldfd int, newfd int) (err error)
 //sys  Fchown(fd int, uid int, gid int) (err error)
 //sys  Fstat(fd int, stat *Stat_t) (err error)
 //sys  Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
index 8f710d01400d1894026031eb2568d5b5ace0a267..400ba9fbc904341babd135fc29f59fac13e0a633 100644 (file)
@@ -12,6 +12,8 @@ import (
        "sync"
        "syscall"
        "unsafe"
+
+       "golang.org/x/sys/internal/unsafeheader"
 )
 
 var (
@@ -113,15 +115,12 @@ func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (d
                return nil, errno
        }
 
-       // Slice memory layout
-       var sl = struct {
-               addr uintptr
-               len  int
-               cap  int
-       }{addr, length, length}
-
-       // Use unsafe to turn sl into a []byte.
-       b := *(*[]byte)(unsafe.Pointer(&sl))
+       // Use unsafe to convert addr into a []byte.
+       var b []byte
+       hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
+       hdr.Data = unsafe.Pointer(addr)
+       hdr.Cap = length
+       hdr.Len = length
 
        // Register mapping in m and return it.
        p := &b[cap(b)-1]
index 219739407bf027d1249bd52c6dd0ebe1c316e465..f8bd50c11ba0c6174c1706f1d998ffeb021b2d6a 100644 (file)
@@ -160,78 +160,28 @@ const (
        BPF_A                                       = 0x10
        BPF_ABS                                     = 0x20
        BPF_ADD                                     = 0x0
-       BPF_ADJ_ROOM_ENCAP_L2_MASK                  = 0xff
-       BPF_ADJ_ROOM_ENCAP_L2_SHIFT                 = 0x38
        BPF_ALU                                     = 0x4
        BPF_ALU64                                   = 0x7
        BPF_AND                                     = 0x50
-       BPF_ANY                                     = 0x0
        BPF_ARSH                                    = 0xc0
        BPF_B                                       = 0x10
        BPF_BUILD_ID_SIZE                           = 0x14
        BPF_CALL                                    = 0x80
-       BPF_DEVCG_ACC_MKNOD                         = 0x1
-       BPF_DEVCG_ACC_READ                          = 0x2
-       BPF_DEVCG_ACC_WRITE                         = 0x4
-       BPF_DEVCG_DEV_BLOCK                         = 0x1
-       BPF_DEVCG_DEV_CHAR                          = 0x2
        BPF_DIV                                     = 0x30
        BPF_DW                                      = 0x18
        BPF_END                                     = 0xd0
-       BPF_EXIST                                   = 0x2
        BPF_EXIT                                    = 0x90
-       BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG         = 0x1
-       BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP          = 0x4
-       BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL     = 0x2
        BPF_FROM_BE                                 = 0x8
        BPF_FROM_LE                                 = 0x0
        BPF_FS_MAGIC                                = 0xcafe4a11
-       BPF_F_ADJ_ROOM_ENCAP_L3_IPV4                = 0x2
-       BPF_F_ADJ_ROOM_ENCAP_L3_IPV6                = 0x4
-       BPF_F_ADJ_ROOM_ENCAP_L4_GRE                 = 0x8
-       BPF_F_ADJ_ROOM_ENCAP_L4_UDP                 = 0x10
-       BPF_F_ADJ_ROOM_FIXED_GSO                    = 0x1
        BPF_F_ALLOW_MULTI                           = 0x2
        BPF_F_ALLOW_OVERRIDE                        = 0x1
        BPF_F_ANY_ALIGNMENT                         = 0x2
-       BPF_F_CLONE                                 = 0x200
-       BPF_F_CTXLEN_MASK                           = 0xfffff00000000
-       BPF_F_CURRENT_CPU                           = 0xffffffff
-       BPF_F_CURRENT_NETNS                         = -0x1
-       BPF_F_DONT_FRAGMENT                         = 0x4
-       BPF_F_FAST_STACK_CMP                        = 0x200
-       BPF_F_HDR_FIELD_MASK                        = 0xf
-       BPF_F_INDEX_MASK                            = 0xffffffff
-       BPF_F_INGRESS                               = 0x1
-       BPF_F_INVALIDATE_HASH                       = 0x2
-       BPF_F_LOCK                                  = 0x4
-       BPF_F_MARK_ENFORCE                          = 0x40
-       BPF_F_MARK_MANGLED_0                        = 0x20
-       BPF_F_MMAPABLE                              = 0x400
-       BPF_F_NO_COMMON_LRU                         = 0x2
-       BPF_F_NO_PREALLOC                           = 0x1
-       BPF_F_NUMA_NODE                             = 0x4
-       BPF_F_PSEUDO_HDR                            = 0x10
        BPF_F_QUERY_EFFECTIVE                       = 0x1
-       BPF_F_RDONLY                                = 0x8
-       BPF_F_RDONLY_PROG                           = 0x80
-       BPF_F_RECOMPUTE_CSUM                        = 0x1
        BPF_F_REPLACE                               = 0x4
-       BPF_F_REUSE_STACKID                         = 0x400
-       BPF_F_SEQ_NUMBER                            = 0x8
-       BPF_F_SKIP_FIELD_MASK                       = 0xff
-       BPF_F_STACK_BUILD_ID                        = 0x20
        BPF_F_STRICT_ALIGNMENT                      = 0x1
-       BPF_F_SYSCTL_BASE_NAME                      = 0x1
        BPF_F_TEST_RND_HI32                         = 0x4
        BPF_F_TEST_STATE_FREQ                       = 0x8
-       BPF_F_TUNINFO_IPV6                          = 0x1
-       BPF_F_USER_BUILD_ID                         = 0x800
-       BPF_F_USER_STACK                            = 0x100
-       BPF_F_WRONLY                                = 0x10
-       BPF_F_WRONLY_PROG                           = 0x100
-       BPF_F_ZERO_CSUM_TX                          = 0x2
-       BPF_F_ZERO_SEED                             = 0x40
        BPF_H                                       = 0x8
        BPF_IMM                                     = 0x0
        BPF_IND                                     = 0x40
@@ -267,7 +217,6 @@ const (
        BPF_MUL                                     = 0x20
        BPF_NEG                                     = 0x80
        BPF_NET_OFF                                 = -0x100000
-       BPF_NOEXIST                                 = 0x1
        BPF_OBJ_NAME_LEN                            = 0x10
        BPF_OR                                      = 0x40
        BPF_PSEUDO_CALL                             = 0x1
@@ -275,12 +224,6 @@ const (
        BPF_PSEUDO_MAP_VALUE                        = 0x2
        BPF_RET                                     = 0x6
        BPF_RSH                                     = 0x70
-       BPF_SK_STORAGE_GET_F_CREATE                 = 0x1
-       BPF_SOCK_OPS_ALL_CB_FLAGS                   = 0xf
-       BPF_SOCK_OPS_RETRANS_CB_FLAG                = 0x2
-       BPF_SOCK_OPS_RTO_CB_FLAG                    = 0x1
-       BPF_SOCK_OPS_RTT_CB_FLAG                    = 0x8
-       BPF_SOCK_OPS_STATE_CB_FLAG                  = 0x4
        BPF_ST                                      = 0x2
        BPF_STX                                     = 0x3
        BPF_SUB                                     = 0x10
@@ -378,12 +321,14 @@ const (
        CLOCK_TXINT                                 = 0x3
        CLONE_ARGS_SIZE_VER0                        = 0x40
        CLONE_ARGS_SIZE_VER1                        = 0x50
+       CLONE_ARGS_SIZE_VER2                        = 0x58
        CLONE_CHILD_CLEARTID                        = 0x200000
        CLONE_CHILD_SETTID                          = 0x1000000
        CLONE_CLEAR_SIGHAND                         = 0x100000000
        CLONE_DETACHED                              = 0x400000
        CLONE_FILES                                 = 0x400
        CLONE_FS                                    = 0x200
+       CLONE_INTO_CGROUP                           = 0x200000000
        CLONE_IO                                    = 0x80000000
        CLONE_NEWCGROUP                             = 0x2000000
        CLONE_NEWIPC                                = 0x8000000
@@ -598,7 +543,9 @@ const (
        FAN_DELETE                                  = 0x200
        FAN_DELETE_SELF                             = 0x400
        FAN_DENY                                    = 0x2
+       FAN_DIR_MODIFY                              = 0x80000
        FAN_ENABLE_AUDIT                            = 0x40
+       FAN_EVENT_INFO_TYPE_DFID_NAME               = 0x2
        FAN_EVENT_INFO_TYPE_FID                     = 0x1
        FAN_EVENT_METADATA_LEN                      = 0x18
        FAN_EVENT_ON_CHILD                          = 0x8000000
@@ -2108,8 +2055,6 @@ const (
        TCOFLUSH                                    = 0x1
        TCOOFF                                      = 0x0
        TCOON                                       = 0x1
-       TCP_BPF_IW                                  = 0x3e9
-       TCP_BPF_SNDCWND_CLAMP                       = 0x3ea
        TCP_CC_INFO                                 = 0x1a
        TCP_CM_INQ                                  = 0x24
        TCP_CONGESTION                              = 0xd
@@ -2165,6 +2110,8 @@ const (
        TCP_USER_TIMEOUT                            = 0x12
        TCP_WINDOW_CLAMP                            = 0xa
        TCP_ZEROCOPY_RECEIVE                        = 0x23
+       TFD_TIMER_ABSTIME                           = 0x1
+       TFD_TIMER_CANCEL_ON_SET                     = 0x2
        TIMER_ABSTIME                               = 0x1
        TIOCM_DTR                                   = 0x2
        TIOCM_LE                                    = 0x1
@@ -2382,8 +2329,9 @@ const (
        XDP_COPY                                    = 0x2
        XDP_FLAGS_DRV_MODE                          = 0x4
        XDP_FLAGS_HW_MODE                           = 0x8
-       XDP_FLAGS_MASK                              = 0xf
+       XDP_FLAGS_MASK                              = 0x1f
        XDP_FLAGS_MODES                             = 0xe
+       XDP_FLAGS_REPLACE                           = 0x10
        XDP_FLAGS_SKB_MODE                          = 0x2
        XDP_FLAGS_UPDATE_IF_NOEXIST                 = 0x1
        XDP_MMAP_OFFSETS                            = 0x1
index 028c9d878f82f33fbad3a46edf413e2f30cfa441..11b25f68c26a85d18a5c8fea7f6f5f012bd9ea0a 100644 (file)
@@ -75,8 +75,10 @@ const (
        FP_XSTATE_MAGIC2                 = 0x46505845
        FS_IOC_ENABLE_VERITY             = 0x40806685
        FS_IOC_GETFLAGS                  = 0x80046601
+       FS_IOC_GET_ENCRYPTION_NONCE      = 0x8010661b
        FS_IOC_GET_ENCRYPTION_POLICY     = 0x400c6615
        FS_IOC_GET_ENCRYPTION_PWSALT     = 0x40106614
+       FS_IOC_SETFLAGS                  = 0x40046602
        FS_IOC_SET_ENCRYPTION_POLICY     = 0x800c6613
        F_GETLK                          = 0xc
        F_GETLK64                        = 0xc
@@ -342,6 +344,8 @@ const (
        TCSETXF                          = 0x5434
        TCSETXW                          = 0x5435
        TCXONC                           = 0x540a
+       TFD_CLOEXEC                      = 0x80000
+       TFD_NONBLOCK                     = 0x800
        TIOCCBRK                         = 0x5428
        TIOCCONS                         = 0x541d
        TIOCEXCL                         = 0x540c
index 005970f7108da73b11ca7346ce73abd3ec258b46..f92cff6ea0d2bcb4082fa7478cba4836b85bfbea 100644 (file)
@@ -75,8 +75,10 @@ const (
        FP_XSTATE_MAGIC2                 = 0x46505845
        FS_IOC_ENABLE_VERITY             = 0x40806685
        FS_IOC_GETFLAGS                  = 0x80086601
+       FS_IOC_GET_ENCRYPTION_NONCE      = 0x8010661b
        FS_IOC_GET_ENCRYPTION_POLICY     = 0x400c6615
        FS_IOC_GET_ENCRYPTION_PWSALT     = 0x40106614
+       FS_IOC_SETFLAGS                  = 0x40086602
        FS_IOC_SET_ENCRYPTION_POLICY     = 0x800c6613
        F_GETLK                          = 0x5
        F_GETLK64                        = 0x5
@@ -343,6 +345,8 @@ const (
        TCSETXF                          = 0x5434
        TCSETXW                          = 0x5435
        TCXONC                           = 0x540a
+       TFD_CLOEXEC                      = 0x80000
+       TFD_NONBLOCK                     = 0x800
        TIOCCBRK                         = 0x5428
        TIOCCONS                         = 0x541d
        TIOCEXCL                         = 0x540c
index 0541f36ee88a75a013644cb9a564a67e9b304a5d..12bcbf88d69fe2b588ba3d02d6d063a2390ec469 100644 (file)
@@ -74,8 +74,10 @@ const (
        FLUSHO                           = 0x1000
        FS_IOC_ENABLE_VERITY             = 0x40806685
        FS_IOC_GETFLAGS                  = 0x80046601
+       FS_IOC_GET_ENCRYPTION_NONCE      = 0x8010661b
        FS_IOC_GET_ENCRYPTION_POLICY     = 0x400c6615
        FS_IOC_GET_ENCRYPTION_PWSALT     = 0x40106614
+       FS_IOC_SETFLAGS                  = 0x40046602
        FS_IOC_SET_ENCRYPTION_POLICY     = 0x800c6613
        F_GETLK                          = 0xc
        F_GETLK64                        = 0xc
@@ -349,6 +351,8 @@ const (
        TCSETXF                          = 0x5434
        TCSETXW                          = 0x5435
        TCXONC                           = 0x540a
+       TFD_CLOEXEC                      = 0x80000
+       TFD_NONBLOCK                     = 0x800
        TIOCCBRK                         = 0x5428
        TIOCCONS                         = 0x541d
        TIOCEXCL                         = 0x540c
index 9ee8d1bc8475e1a1344fa6b2f3656812b0ac20dd..8b0e024b944a0a43c9015f6be18fb8aef8827798 100644 (file)
@@ -77,8 +77,10 @@ const (
        FPSIMD_MAGIC                     = 0x46508001
        FS_IOC_ENABLE_VERITY             = 0x40806685
        FS_IOC_GETFLAGS                  = 0x80086601
+       FS_IOC_GET_ENCRYPTION_NONCE      = 0x8010661b
        FS_IOC_GET_ENCRYPTION_POLICY     = 0x400c6615
        FS_IOC_GET_ENCRYPTION_PWSALT     = 0x40106614
+       FS_IOC_SETFLAGS                  = 0x40086602
        FS_IOC_SET_ENCRYPTION_POLICY     = 0x800c6613
        F_GETLK                          = 0x5
        F_GETLK64                        = 0x5
@@ -336,6 +338,8 @@ const (
        TCSETXF                          = 0x5434
        TCSETXW                          = 0x5435
        TCXONC                           = 0x540a
+       TFD_CLOEXEC                      = 0x80000
+       TFD_NONBLOCK                     = 0x800
        TIOCCBRK                         = 0x5428
        TIOCCONS                         = 0x541d
        TIOCEXCL                         = 0x540c
index 4826bd70509ffddd61deb11549f9f896959f49a7..eeadea943f3cd02374d5184633b28a5fc1219a85 100644 (file)
@@ -74,8 +74,10 @@ const (
        FLUSHO                           = 0x2000
        FS_IOC_ENABLE_VERITY             = 0x80806685
        FS_IOC_GETFLAGS                  = 0x40046601
+       FS_IOC_GET_ENCRYPTION_NONCE      = 0x4010661b
        FS_IOC_GET_ENCRYPTION_POLICY     = 0x800c6615
        FS_IOC_GET_ENCRYPTION_PWSALT     = 0x80106614
+       FS_IOC_SETFLAGS                  = 0x80046602
        FS_IOC_SET_ENCRYPTION_POLICY     = 0x400c6613
        F_GETLK                          = 0x21
        F_GETLK64                        = 0x21
@@ -339,6 +341,8 @@ const (
        TCSETSW                          = 0x540f
        TCSETSW2                         = 0x8030542c
        TCXONC                           = 0x5406
+       TFD_CLOEXEC                      = 0x80000
+       TFD_NONBLOCK                     = 0x80
        TIOCCBRK                         = 0x5428
        TIOCCONS                         = 0x80047478
        TIOCEXCL                         = 0x740d
index 2346dc554d7f09441ff9374a04bbf4eed1eb08c1..0be6c4ccc0e698c2a2b74afa77de4b431ec6f3f4 100644 (file)
@@ -74,8 +74,10 @@ const (
        FLUSHO                           = 0x2000
        FS_IOC_ENABLE_VERITY             = 0x80806685
        FS_IOC_GETFLAGS                  = 0x40086601
+       FS_IOC_GET_ENCRYPTION_NONCE      = 0x4010661b
        FS_IOC_GET_ENCRYPTION_POLICY     = 0x800c6615
        FS_IOC_GET_ENCRYPTION_PWSALT     = 0x80106614
+       FS_IOC_SETFLAGS                  = 0x80086602
        FS_IOC_SET_ENCRYPTION_POLICY     = 0x400c6613
        F_GETLK                          = 0xe
        F_GETLK64                        = 0xe
@@ -339,6 +341,8 @@ const (
        TCSETSW                          = 0x540f
        TCSETSW2                         = 0x8030542c
        TCXONC                           = 0x5406
+       TFD_CLOEXEC                      = 0x80000
+       TFD_NONBLOCK                     = 0x80
        TIOCCBRK                         = 0x5428
        TIOCCONS                         = 0x80047478
        TIOCEXCL                         = 0x740d
index e758b61e372b4b36bc2df40b9fc01c4cb261d3d2..0880b745c109d8fcda0976725fbc1cf8ba908228 100644 (file)
@@ -74,8 +74,10 @@ const (
        FLUSHO                           = 0x2000
        FS_IOC_ENABLE_VERITY             = 0x80806685
        FS_IOC_GETFLAGS                  = 0x40086601
+       FS_IOC_GET_ENCRYPTION_NONCE      = 0x4010661b
        FS_IOC_GET_ENCRYPTION_POLICY     = 0x800c6615
        FS_IOC_GET_ENCRYPTION_PWSALT     = 0x80106614
+       FS_IOC_SETFLAGS                  = 0x80086602
        FS_IOC_SET_ENCRYPTION_POLICY     = 0x400c6613
        F_GETLK                          = 0xe
        F_GETLK64                        = 0xe
@@ -339,6 +341,8 @@ const (
        TCSETSW                          = 0x540f
        TCSETSW2                         = 0x8030542c
        TCXONC                           = 0x5406
+       TFD_CLOEXEC                      = 0x80000
+       TFD_NONBLOCK                     = 0x80
        TIOCCBRK                         = 0x5428
        TIOCCONS                         = 0x80047478
        TIOCEXCL                         = 0x740d
index 2dfe6bba1b44c584c708e37865d9c8dab29d6cb4..c8a66627aa4db3c500127b806bd4b931e2b2f4a3 100644 (file)
@@ -74,8 +74,10 @@ const (
        FLUSHO                           = 0x2000
        FS_IOC_ENABLE_VERITY             = 0x80806685
        FS_IOC_GETFLAGS                  = 0x40046601
+       FS_IOC_GET_ENCRYPTION_NONCE      = 0x4010661b
        FS_IOC_GET_ENCRYPTION_POLICY     = 0x800c6615
        FS_IOC_GET_ENCRYPTION_PWSALT     = 0x80106614
+       FS_IOC_SETFLAGS                  = 0x80046602
        FS_IOC_SET_ENCRYPTION_POLICY     = 0x400c6613
        F_GETLK                          = 0x21
        F_GETLK64                        = 0x21
@@ -339,6 +341,8 @@ const (
        TCSETSW                          = 0x540f
        TCSETSW2                         = 0x8030542c
        TCXONC                           = 0x5406
+       TFD_CLOEXEC                      = 0x80000
+       TFD_NONBLOCK                     = 0x80
        TIOCCBRK                         = 0x5428
        TIOCCONS                         = 0x80047478
        TIOCEXCL                         = 0x740d
index 51858667017c3cc5da88317737c16648de1f7819..97aae63f16cb519dd5596fd75170d92e2c974d3e 100644 (file)
@@ -74,8 +74,10 @@ const (
        FLUSHO                           = 0x800000
        FS_IOC_ENABLE_VERITY             = 0x80806685
        FS_IOC_GETFLAGS                  = 0x40086601
+       FS_IOC_GET_ENCRYPTION_NONCE      = 0x4010661b
        FS_IOC_GET_ENCRYPTION_POLICY     = 0x800c6615
        FS_IOC_GET_ENCRYPTION_PWSALT     = 0x80106614
+       FS_IOC_SETFLAGS                  = 0x80086602
        FS_IOC_SET_ENCRYPTION_POLICY     = 0x400c6613
        F_GETLK                          = 0x5
        F_GETLK64                        = 0xc
@@ -393,6 +395,8 @@ const (
        TCSETSF                          = 0x802c7416
        TCSETSW                          = 0x802c7415
        TCXONC                           = 0x2000741e
+       TFD_CLOEXEC                      = 0x80000
+       TFD_NONBLOCK                     = 0x800
        TIOCCBRK                         = 0x5428
        TIOCCONS                         = 0x541d
        TIOCEXCL                         = 0x540c
index 4231b20b507395e75b6a1d4d92c306d641a6dfea..b0c3b0664f4e3a85af181f39e62fa51a25db3c1a 100644 (file)
@@ -74,8 +74,10 @@ const (
        FLUSHO                           = 0x800000
        FS_IOC_ENABLE_VERITY             = 0x80806685
        FS_IOC_GETFLAGS                  = 0x40086601
+       FS_IOC_GET_ENCRYPTION_NONCE      = 0x4010661b
        FS_IOC_GET_ENCRYPTION_POLICY     = 0x800c6615
        FS_IOC_GET_ENCRYPTION_PWSALT     = 0x80106614
+       FS_IOC_SETFLAGS                  = 0x80086602
        FS_IOC_SET_ENCRYPTION_POLICY     = 0x400c6613
        F_GETLK                          = 0x5
        F_GETLK64                        = 0xc
@@ -393,6 +395,8 @@ const (
        TCSETSF                          = 0x802c7416
        TCSETSW                          = 0x802c7415
        TCXONC                           = 0x2000741e
+       TFD_CLOEXEC                      = 0x80000
+       TFD_NONBLOCK                     = 0x800
        TIOCCBRK                         = 0x5428
        TIOCCONS                         = 0x541d
        TIOCEXCL                         = 0x540c
index 6a0b2d29399cc913ba4333eb06117768da8fdcab..0c0518193555b5f9ceda5c88aab52d0b1628e534 100644 (file)
@@ -74,8 +74,10 @@ const (
        FLUSHO                           = 0x1000
        FS_IOC_ENABLE_VERITY             = 0x40806685
        FS_IOC_GETFLAGS                  = 0x80086601
+       FS_IOC_GET_ENCRYPTION_NONCE      = 0x8010661b
        FS_IOC_GET_ENCRYPTION_POLICY     = 0x400c6615
        FS_IOC_GET_ENCRYPTION_PWSALT     = 0x40106614
+       FS_IOC_SETFLAGS                  = 0x40086602
        FS_IOC_SET_ENCRYPTION_POLICY     = 0x800c6613
        F_GETLK                          = 0x5
        F_GETLK64                        = 0x5
@@ -330,6 +332,8 @@ const (
        TCSETXF                          = 0x5434
        TCSETXW                          = 0x5435
        TCXONC                           = 0x540a
+       TFD_CLOEXEC                      = 0x80000
+       TFD_NONBLOCK                     = 0x800
        TIOCCBRK                         = 0x5428
        TIOCCONS                         = 0x541d
        TIOCEXCL                         = 0x540c
index 95e950fc843bb12b7618b7a071c8553c9a2cff30..0b96bd462e932a523a5db2aa646d3bc836cb0d2e 100644 (file)
@@ -74,8 +74,10 @@ const (
        FLUSHO                           = 0x1000
        FS_IOC_ENABLE_VERITY             = 0x40806685
        FS_IOC_GETFLAGS                  = 0x80086601
+       FS_IOC_GET_ENCRYPTION_NONCE      = 0x8010661b
        FS_IOC_GET_ENCRYPTION_POLICY     = 0x400c6615
        FS_IOC_GET_ENCRYPTION_PWSALT     = 0x40106614
+       FS_IOC_SETFLAGS                  = 0x40086602
        FS_IOC_SET_ENCRYPTION_POLICY     = 0x800c6613
        F_GETLK                          = 0x5
        F_GETLK64                        = 0x5
@@ -403,6 +405,8 @@ const (
        TCSETXF                          = 0x5434
        TCSETXW                          = 0x5435
        TCXONC                           = 0x540a
+       TFD_CLOEXEC                      = 0x80000
+       TFD_NONBLOCK                     = 0x800
        TIOCCBRK                         = 0x5428
        TIOCCONS                         = 0x541d
        TIOCEXCL                         = 0x540c
index 079762fa98964165ac630abe901185be715a2793..bd5c3057796d95298903c77ac61f5767a3a0ed7c 100644 (file)
@@ -78,8 +78,10 @@ const (
        FLUSHO                           = 0x1000
        FS_IOC_ENABLE_VERITY             = 0x80806685
        FS_IOC_GETFLAGS                  = 0x40086601
+       FS_IOC_GET_ENCRYPTION_NONCE      = 0x4010661b
        FS_IOC_GET_ENCRYPTION_POLICY     = 0x800c6615
        FS_IOC_GET_ENCRYPTION_PWSALT     = 0x80106614
+       FS_IOC_SETFLAGS                  = 0x80086602
        FS_IOC_SET_ENCRYPTION_POLICY     = 0x400c6613
        F_GETLK                          = 0x7
        F_GETLK64                        = 0x7
@@ -392,6 +394,8 @@ const (
        TCSETSW                          = 0x8024540a
        TCSETSW2                         = 0x802c540e
        TCXONC                           = 0x20005406
+       TFD_CLOEXEC                      = 0x400000
+       TFD_NONBLOCK                     = 0x4000
        TIOCCBRK                         = 0x2000747a
        TIOCCONS                         = 0x20007424
        TIOCEXCL                         = 0x2000740d
index c1cc0a415fe7cffc9aaea9b088f047eb815e7ab9..23e94d3663c7df6f268ddf892077e494f900140d 100644 (file)
@@ -966,6 +966,16 @@ func Getsid(pid int) (sid int, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Gettimeofday(tp *Timeval) (err error) {
+       _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getuid() (uid int) {
        r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
        uid = int(r0)
@@ -1709,18 +1719,6 @@ func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) {
-       r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-       sec = int32(r0)
-       usec = int32(r1)
-       if e1 != 0 {
-               err = errnoErr(e1)
-       }
-       return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fstat(fd int, stat *Stat_t) (err error) {
        _, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
        if e1 != 0 {
index a3fc4900412cf5a13f83d3f09d506240f7dc724c..e2ffb3bed334cbf6da8189ad81116978c95de074 100644 (file)
@@ -1376,6 +1376,21 @@ func libc_getsid_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Gettimeofday(tp *Timeval) (err error) {
+       _, _, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+func libc_gettimeofday_trampoline()
+
+//go:linkname libc_gettimeofday libc_gettimeofday
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getuid() (uid int) {
        r0, _, _ := syscall_rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0)
        uid = int(r0)
@@ -2357,23 +2372,6 @@ func libc_ptrace_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) {
-       r0, r1, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
-       sec = int32(r0)
-       usec = int32(r1)
-       if e1 != 0 {
-               err = errnoErr(e1)
-       }
-       return
-}
-
-func libc_gettimeofday_trampoline()
-
-//go:linkname libc_gettimeofday libc_gettimeofday
-//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fstat(fd int, stat *Stat_t) (err error) {
        _, _, e1 := syscall_syscall(funcPC(libc_fstat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
        if e1 != 0 {
index f8e5c37c5ca0f49907ceb4b899a4e70e89734d89..102561730abef0d5138021d066535c28f9781b8f 100644 (file)
@@ -966,6 +966,16 @@ func Getsid(pid int) (sid int, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Gettimeofday(tp *Timeval) (err error) {
+       _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getuid() (uid int) {
        r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
        uid = int(r0)
@@ -1709,18 +1719,6 @@ func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) {
-       r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-       sec = int64(r0)
-       usec = int32(r1)
-       if e1 != 0 {
-               err = errnoErr(e1)
-       }
-       return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fstat(fd int, stat *Stat_t) (err error) {
        _, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
        if e1 != 0 {
index 50d6437e6b8104468a7fe1aced4c4e2e5dfe48d9..c67e336e2ab8e1e14e9c84812a79c4c798540d07 100644 (file)
@@ -1376,6 +1376,21 @@ func libc_getsid_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Gettimeofday(tp *Timeval) (err error) {
+       _, _, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+func libc_gettimeofday_trampoline()
+
+//go:linkname libc_gettimeofday libc_gettimeofday
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getuid() (uid int) {
        r0, _, _ := syscall_rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0)
        uid = int(r0)
@@ -2357,23 +2372,6 @@ func libc_ptrace_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) {
-       r0, r1, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
-       sec = int64(r0)
-       usec = int32(r1)
-       if e1 != 0 {
-               err = errnoErr(e1)
-       }
-       return
-}
-
-func libc_gettimeofday_trampoline()
-
-//go:linkname libc_gettimeofday libc_gettimeofday
-//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fstat(fd int, stat *Stat_t) (err error) {
        _, _, e1 := syscall_syscall(funcPC(libc_fstat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
        if e1 != 0 {
index cea04e041c44c607d5369df5d947b9e5d8831e8d..d34e6df2fe0e41031f9a72e170784458bf700769 100644 (file)
@@ -966,6 +966,16 @@ func Getsid(pid int) (sid int, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Gettimeofday(tp *Timeval) (err error) {
+       _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getuid() (uid int) {
        r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
        uid = int(r0)
@@ -1682,18 +1692,6 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) {
-       r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-       sec = int32(r0)
-       usec = int32(r1)
-       if e1 != 0 {
-               err = errnoErr(e1)
-       }
-       return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fstat(fd int, stat *Stat_t) (err error) {
        _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
        if e1 != 0 {
index 63103950ca7cde81aeea0e2d969dd704d7c7fa8b..b759757a77a038ea1ab347630239ef0c8a40bd7a 100644 (file)
@@ -1376,6 +1376,21 @@ func libc_getsid_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Gettimeofday(tp *Timeval) (err error) {
+       _, _, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+func libc_gettimeofday_trampoline()
+
+//go:linkname libc_gettimeofday libc_gettimeofday
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getuid() (uid int) {
        r0, _, _ := syscall_rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0)
        uid = int(r0)
@@ -2342,23 +2357,6 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) {
-       r0, r1, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
-       sec = int32(r0)
-       usec = int32(r1)
-       if e1 != 0 {
-               err = errnoErr(e1)
-       }
-       return
-}
-
-func libc_gettimeofday_trampoline()
-
-//go:linkname libc_gettimeofday libc_gettimeofday
-//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fstat(fd int, stat *Stat_t) (err error) {
        _, _, e1 := syscall_syscall(funcPC(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
        if e1 != 0 {
index 8c3bb3a25d15e7af389325a8e67763c9e283485f..8d39a09f7214ace0d396a0685a32bb24f5e2e1d7 100644 (file)
@@ -966,6 +966,16 @@ func Getsid(pid int) (sid int, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Gettimeofday(tp *Timeval) (err error) {
+       _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getuid() (uid int) {
        r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
        uid = int(r0)
@@ -1682,18 +1692,6 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) {
-       r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-       sec = int64(r0)
-       usec = int32(r1)
-       if e1 != 0 {
-               err = errnoErr(e1)
-       }
-       return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fstat(fd int, stat *Stat_t) (err error) {
        _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
        if e1 != 0 {
index a8709f72dd7664b7ecc53fd8d04a69ab60e18ca2..b2886126003b5730fdc98a1f38be77a41234759d 100644 (file)
@@ -1376,6 +1376,21 @@ func libc_getsid_trampoline()
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Gettimeofday(tp *Timeval) (err error) {
+       _, _, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+func libc_gettimeofday_trampoline()
+
+//go:linkname libc_gettimeofday libc_gettimeofday
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getuid() (uid int) {
        r0, _, _ := syscall_rawSyscall(funcPC(libc_getuid_trampoline), 0, 0, 0)
        uid = int(r0)
@@ -2342,23 +2357,6 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) {
-       r0, r1, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
-       sec = int64(r0)
-       usec = int32(r1)
-       if e1 != 0 {
-               err = errnoErr(e1)
-       }
-       return
-}
-
-func libc_gettimeofday_trampoline()
-
-//go:linkname libc_gettimeofday libc_gettimeofday
-//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fstat(fd int, stat *Stat_t) (err error) {
        _, _, e1 := syscall_syscall(funcPC(libc_fstat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
        if e1 != 0 {
index fd2dae8e57797e93c6451a66b10876298cfea055..df217825f06941ec729c87455f1dc7739f22ee5a 100644 (file)
@@ -1450,6 +1450,37 @@ func Sysinfo(info *Sysinfo_t) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func TimerfdCreate(clockid int, flags int) (fd int, err error) {
+       r0, _, e1 := RawSyscall(SYS_TIMERFD_CREATE, uintptr(clockid), uintptr(flags), 0)
+       fd = int(r0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func TimerfdGettime(fd int, currValue *ItimerSpec) (err error) {
+       _, _, e1 := RawSyscall(SYS_TIMERFD_GETTIME, uintptr(fd), uintptr(unsafe.Pointer(currValue)), 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func TimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error) {
+       _, _, e1 := RawSyscall6(SYS_TIMERFD_SETTIME, uintptr(fd), uintptr(flags), uintptr(unsafe.Pointer(newValue)), uintptr(unsafe.Pointer(oldValue)), 0, 0)
+       if e1 != 0 {
+               err = errnoErr(e1)
+       }
+       return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) {
        _, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
        if e1 != 0 {
index ba63af7b08d899c36e1ff7801066a9937fdda2c6..19ebd3ff75f9bbe6fe2b6d0f20edbecca42811fb 100644 (file)
@@ -55,7 +55,7 @@ func pipe(p *[2]_C_int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Dup2(oldfd int, newfd int) (err error) {
+func dup2(oldfd int, newfd int) (err error) {
        _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
        if e1 != 0 {
                err = errnoErr(e1)
index f64adef415a956db86e88967592967c1cb4307cc..5c562182a198bd4675a1ceb084babd9bdc998a30 100644 (file)
@@ -45,7 +45,7 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Dup2(oldfd int, newfd int) (err error) {
+func dup2(oldfd int, newfd int) (err error) {
        _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
        if e1 != 0 {
                err = errnoErr(e1)
index ac19523e8873890130bca161b20e8c0b60e967d8..dc69d99c6129f4e96415e359fd69bb15607bac4f 100644 (file)
@@ -234,7 +234,7 @@ func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Dup2(oldfd int, newfd int) (err error) {
+func dup2(oldfd int, newfd int) (err error) {
        _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
        if e1 != 0 {
                err = errnoErr(e1)
index f0d2890b161089a9b0549bb4e6ef99e0530cc2f2..1b897dee05d1b98a709945d35c9590a439040c09 100644 (file)
@@ -151,7 +151,7 @@ func Getgid() (gid int) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Getrlimit(resource int, rlim *Rlimit) (err error) {
+func getrlimit(resource int, rlim *Rlimit) (err error) {
        _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
        if e1 != 0 {
                err = errnoErr(e1)
@@ -307,7 +307,7 @@ func Setresuid(ruid int, euid int, suid int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setrlimit(resource int, rlim *Rlimit) (err error) {
+func setrlimit(resource int, rlim *Rlimit) (err error) {
        _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
        if e1 != 0 {
                err = errnoErr(e1)
index aecbbca7542b88bfd956c2eae75ce0419993e98a..49186843ae5216985ef7399ab2d94feb75d9fe25 100644 (file)
@@ -45,7 +45,7 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Dup2(oldfd int, newfd int) (err error) {
+func dup2(oldfd int, newfd int) (err error) {
        _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
        if e1 != 0 {
                err = errnoErr(e1)
index 424fb7fb6014c79a8b92d3dedbcb4172496b86c3..9171d3bd2a69a07194b186d98dabe50f1ebdb82d 100644 (file)
@@ -45,7 +45,7 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Dup2(oldfd int, newfd int) (err error) {
+func dup2(oldfd int, newfd int) (err error) {
        _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
        if e1 != 0 {
                err = errnoErr(e1)
index 28c7239cf641fe1d4aef68f43823f463572dfd4f..82286f04f9a3df75a422551a7565b41d8fd22b59 100644 (file)
@@ -45,7 +45,7 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Dup2(oldfd int, newfd int) (err error) {
+func dup2(oldfd int, newfd int) (err error) {
        _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
        if e1 != 0 {
                err = errnoErr(e1)
index 84596b300a63ba07d2fa1c0ed0ccadd0d0a1397c..15920621c473e06bb4cdf0dbd4cedc161a1ca48f 100644 (file)
@@ -45,7 +45,7 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Dup2(oldfd int, newfd int) (err error) {
+func dup2(oldfd int, newfd int) (err error) {
        _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
        if e1 != 0 {
                err = errnoErr(e1)
index de022639d68a65744feee4011db735bcd3cedb97..73a42e2ccbaa18549a2aed06828d3eb4e9c2c8b6 100644 (file)
@@ -45,7 +45,7 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Dup2(oldfd int, newfd int) (err error) {
+func dup2(oldfd int, newfd int) (err error) {
        _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
        if e1 != 0 {
                err = errnoErr(e1)
index 888f21d37ac4a263b3eae69d64f5b26a82025cc2..6b85595366a1032d44e8307ab097fd928a34b113 100644 (file)
@@ -45,7 +45,7 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Dup2(oldfd int, newfd int) (err error) {
+func dup2(oldfd int, newfd int) (err error) {
        _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
        if e1 != 0 {
                err = errnoErr(e1)
index 9bc353f0c42d8d24adf93abc2aa1aca317593007..d7032ab1e4ad85de61475a198f1703297f4591f2 100644 (file)
@@ -45,7 +45,7 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Dup2(oldfd int, newfd int) (err error) {
+func dup2(oldfd int, newfd int) (err error) {
        _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
        if e1 != 0 {
                err = errnoErr(e1)
index 854e816d67248a1b10c67d3da685828823a57f1c..bcbbdd906e8a619ae7eeb06527409125e286d3dc 100644 (file)
@@ -72,7 +72,7 @@ func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Dup2(oldfd int, newfd int) (err error) {
+func dup2(oldfd int, newfd int) (err error) {
        _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
        if e1 != 0 {
                err = errnoErr(e1)
index 37dcc74c2de5222de9296872f19deb332b04b3ee..102f1ab4750b45060370e0f0e9d3d107883261d5 100644 (file)
@@ -1,4 +1,4 @@
-// mksysctl_openbsd.pl
+// go run mksysctl_openbsd.go
 // Code generated by the command above; DO NOT EDIT.
 
 // +build 386,openbsd
@@ -30,6 +30,7 @@ var sysctlMib = []mibentry{
        {"hw.model", []_C_int{6, 2}},
        {"hw.ncpu", []_C_int{6, 3}},
        {"hw.ncpufound", []_C_int{6, 21}},
+       {"hw.ncpuonline", []_C_int{6, 25}},
        {"hw.pagesize", []_C_int{6, 7}},
        {"hw.physmem", []_C_int{6, 19}},
        {"hw.product", []_C_int{6, 15}},
index fe6caa6eb7f2f47eb2be49c51814a65fc2899905..4866fced8ae8a0de6f381c3b5b920fb911d8bbaf 100644 (file)
@@ -31,6 +31,7 @@ var sysctlMib = []mibentry{
        {"hw.model", []_C_int{6, 2}},
        {"hw.ncpu", []_C_int{6, 3}},
        {"hw.ncpufound", []_C_int{6, 21}},
+       {"hw.ncpuonline", []_C_int{6, 25}},
        {"hw.pagesize", []_C_int{6, 7}},
        {"hw.perfpolicy", []_C_int{6, 23}},
        {"hw.physmem", []_C_int{6, 19}},
index 6eb8c0b086a6281809a069bf304412412e4940ab..d3801eb24b38b928738c5018dd9570da10af9aa9 100644 (file)
@@ -30,6 +30,7 @@ var sysctlMib = []mibentry{
        {"hw.model", []_C_int{6, 2}},
        {"hw.ncpu", []_C_int{6, 3}},
        {"hw.ncpufound", []_C_int{6, 21}},
+       {"hw.ncpuonline", []_C_int{6, 25}},
        {"hw.pagesize", []_C_int{6, 7}},
        {"hw.physmem", []_C_int{6, 19}},
        {"hw.product", []_C_int{6, 15}},
index 6f79227d745764ce598d57104597a5ea07bd4240..b91c2ae0f015f37b39474efcdfd760cf2b64a748 100644 (file)
@@ -125,9 +125,9 @@ type Statfs_t struct {
        Owner       uint32
        Fsid        Fsid
        Charspare   [80]int8
-       Fstypename  [16]int8
-       Mntfromname [1024]int8
-       Mntonname   [1024]int8
+       Fstypename  [16]byte
+       Mntfromname [1024]byte
+       Mntonname   [1024]byte
 }
 
 type statfs_freebsd11_t struct {
@@ -150,9 +150,9 @@ type statfs_freebsd11_t struct {
        Owner       uint32
        Fsid        Fsid
        Charspare   [80]int8
-       Fstypename  [16]int8
-       Mntfromname [88]int8
-       Mntonname   [88]int8
+       Fstypename  [16]byte
+       Mntfromname [88]byte
+       Mntonname   [88]byte
 }
 
 type Flock_t struct {
index af5ab4552fa96d8e052b25e0333842dbae0a5dca..27d67ac8f57fc919801fd48836e721c7a5f90303 100644 (file)
@@ -18,6 +18,11 @@ type (
        _C_long_long int64
 )
 
+type ItimerSpec struct {
+       Interval Timespec
+       Value    Timespec
+}
+
 const (
        TIME_OK    = 0x0
        TIME_INS   = 0x1
@@ -1866,175 +1871,249 @@ const (
 )
 
 const (
-       BPF_REG_0                             = 0x0
-       BPF_REG_1                             = 0x1
-       BPF_REG_2                             = 0x2
-       BPF_REG_3                             = 0x3
-       BPF_REG_4                             = 0x4
-       BPF_REG_5                             = 0x5
-       BPF_REG_6                             = 0x6
-       BPF_REG_7                             = 0x7
-       BPF_REG_8                             = 0x8
-       BPF_REG_9                             = 0x9
-       BPF_REG_10                            = 0xa
-       BPF_MAP_CREATE                        = 0x0
-       BPF_MAP_LOOKUP_ELEM                   = 0x1
-       BPF_MAP_UPDATE_ELEM                   = 0x2
-       BPF_MAP_DELETE_ELEM                   = 0x3
-       BPF_MAP_GET_NEXT_KEY                  = 0x4
-       BPF_PROG_LOAD                         = 0x5
-       BPF_OBJ_PIN                           = 0x6
-       BPF_OBJ_GET                           = 0x7
-       BPF_PROG_ATTACH                       = 0x8
-       BPF_PROG_DETACH                       = 0x9
-       BPF_PROG_TEST_RUN                     = 0xa
-       BPF_PROG_GET_NEXT_ID                  = 0xb
-       BPF_MAP_GET_NEXT_ID                   = 0xc
-       BPF_PROG_GET_FD_BY_ID                 = 0xd
-       BPF_MAP_GET_FD_BY_ID                  = 0xe
-       BPF_OBJ_GET_INFO_BY_FD                = 0xf
-       BPF_PROG_QUERY                        = 0x10
-       BPF_RAW_TRACEPOINT_OPEN               = 0x11
-       BPF_BTF_LOAD                          = 0x12
-       BPF_BTF_GET_FD_BY_ID                  = 0x13
-       BPF_TASK_FD_QUERY                     = 0x14
-       BPF_MAP_LOOKUP_AND_DELETE_ELEM        = 0x15
-       BPF_MAP_FREEZE                        = 0x16
-       BPF_BTF_GET_NEXT_ID                   = 0x17
-       BPF_MAP_TYPE_UNSPEC                   = 0x0
-       BPF_MAP_TYPE_HASH                     = 0x1
-       BPF_MAP_TYPE_ARRAY                    = 0x2
-       BPF_MAP_TYPE_PROG_ARRAY               = 0x3
-       BPF_MAP_TYPE_PERF_EVENT_ARRAY         = 0x4
-       BPF_MAP_TYPE_PERCPU_HASH              = 0x5
-       BPF_MAP_TYPE_PERCPU_ARRAY             = 0x6
-       BPF_MAP_TYPE_STACK_TRACE              = 0x7
-       BPF_MAP_TYPE_CGROUP_ARRAY             = 0x8
-       BPF_MAP_TYPE_LRU_HASH                 = 0x9
-       BPF_MAP_TYPE_LRU_PERCPU_HASH          = 0xa
-       BPF_MAP_TYPE_LPM_TRIE                 = 0xb
-       BPF_MAP_TYPE_ARRAY_OF_MAPS            = 0xc
-       BPF_MAP_TYPE_HASH_OF_MAPS             = 0xd
-       BPF_MAP_TYPE_DEVMAP                   = 0xe
-       BPF_MAP_TYPE_SOCKMAP                  = 0xf
-       BPF_MAP_TYPE_CPUMAP                   = 0x10
-       BPF_MAP_TYPE_XSKMAP                   = 0x11
-       BPF_MAP_TYPE_SOCKHASH                 = 0x12
-       BPF_MAP_TYPE_CGROUP_STORAGE           = 0x13
-       BPF_MAP_TYPE_REUSEPORT_SOCKARRAY      = 0x14
-       BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE    = 0x15
-       BPF_MAP_TYPE_QUEUE                    = 0x16
-       BPF_MAP_TYPE_STACK                    = 0x17
-       BPF_MAP_TYPE_SK_STORAGE               = 0x18
-       BPF_MAP_TYPE_DEVMAP_HASH              = 0x19
-       BPF_PROG_TYPE_UNSPEC                  = 0x0
-       BPF_PROG_TYPE_SOCKET_FILTER           = 0x1
-       BPF_PROG_TYPE_KPROBE                  = 0x2
-       BPF_PROG_TYPE_SCHED_CLS               = 0x3
-       BPF_PROG_TYPE_SCHED_ACT               = 0x4
-       BPF_PROG_TYPE_TRACEPOINT              = 0x5
-       BPF_PROG_TYPE_XDP                     = 0x6
-       BPF_PROG_TYPE_PERF_EVENT              = 0x7
-       BPF_PROG_TYPE_CGROUP_SKB              = 0x8
-       BPF_PROG_TYPE_CGROUP_SOCK             = 0x9
-       BPF_PROG_TYPE_LWT_IN                  = 0xa
-       BPF_PROG_TYPE_LWT_OUT                 = 0xb
-       BPF_PROG_TYPE_LWT_XMIT                = 0xc
-       BPF_PROG_TYPE_SOCK_OPS                = 0xd
-       BPF_PROG_TYPE_SK_SKB                  = 0xe
-       BPF_PROG_TYPE_CGROUP_DEVICE           = 0xf
-       BPF_PROG_TYPE_SK_MSG                  = 0x10
-       BPF_PROG_TYPE_RAW_TRACEPOINT          = 0x11
-       BPF_PROG_TYPE_CGROUP_SOCK_ADDR        = 0x12
-       BPF_PROG_TYPE_LWT_SEG6LOCAL           = 0x13
-       BPF_PROG_TYPE_LIRC_MODE2              = 0x14
-       BPF_PROG_TYPE_SK_REUSEPORT            = 0x15
-       BPF_PROG_TYPE_FLOW_DISSECTOR          = 0x16
-       BPF_PROG_TYPE_CGROUP_SYSCTL           = 0x17
-       BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE = 0x18
-       BPF_PROG_TYPE_CGROUP_SOCKOPT          = 0x19
-       BPF_PROG_TYPE_TRACING                 = 0x1a
-       BPF_CGROUP_INET_INGRESS               = 0x0
-       BPF_CGROUP_INET_EGRESS                = 0x1
-       BPF_CGROUP_INET_SOCK_CREATE           = 0x2
-       BPF_CGROUP_SOCK_OPS                   = 0x3
-       BPF_SK_SKB_STREAM_PARSER              = 0x4
-       BPF_SK_SKB_STREAM_VERDICT             = 0x5
-       BPF_CGROUP_DEVICE                     = 0x6
-       BPF_SK_MSG_VERDICT                    = 0x7
-       BPF_CGROUP_INET4_BIND                 = 0x8
-       BPF_CGROUP_INET6_BIND                 = 0x9
-       BPF_CGROUP_INET4_CONNECT              = 0xa
-       BPF_CGROUP_INET6_CONNECT              = 0xb
-       BPF_CGROUP_INET4_POST_BIND            = 0xc
-       BPF_CGROUP_INET6_POST_BIND            = 0xd
-       BPF_CGROUP_UDP4_SENDMSG               = 0xe
-       BPF_CGROUP_UDP6_SENDMSG               = 0xf
-       BPF_LIRC_MODE2                        = 0x10
-       BPF_FLOW_DISSECTOR                    = 0x11
-       BPF_CGROUP_SYSCTL                     = 0x12
-       BPF_CGROUP_UDP4_RECVMSG               = 0x13
-       BPF_CGROUP_UDP6_RECVMSG               = 0x14
-       BPF_CGROUP_GETSOCKOPT                 = 0x15
-       BPF_CGROUP_SETSOCKOPT                 = 0x16
-       BPF_TRACE_RAW_TP                      = 0x17
-       BPF_TRACE_FENTRY                      = 0x18
-       BPF_TRACE_FEXIT                       = 0x19
-       BPF_STACK_BUILD_ID_EMPTY              = 0x0
-       BPF_STACK_BUILD_ID_VALID              = 0x1
-       BPF_STACK_BUILD_ID_IP                 = 0x2
-       BPF_ADJ_ROOM_NET                      = 0x0
-       BPF_ADJ_ROOM_MAC                      = 0x1
-       BPF_HDR_START_MAC                     = 0x0
-       BPF_HDR_START_NET                     = 0x1
-       BPF_LWT_ENCAP_SEG6                    = 0x0
-       BPF_LWT_ENCAP_SEG6_INLINE             = 0x1
-       BPF_LWT_ENCAP_IP                      = 0x2
-       BPF_OK                                = 0x0
-       BPF_DROP                              = 0x2
-       BPF_REDIRECT                          = 0x7
-       BPF_LWT_REROUTE                       = 0x80
-       BPF_SOCK_OPS_VOID                     = 0x0
-       BPF_SOCK_OPS_TIMEOUT_INIT             = 0x1
-       BPF_SOCK_OPS_RWND_INIT                = 0x2
-       BPF_SOCK_OPS_TCP_CONNECT_CB           = 0x3
-       BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB    = 0x4
-       BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB   = 0x5
-       BPF_SOCK_OPS_NEEDS_ECN                = 0x6
-       BPF_SOCK_OPS_BASE_RTT                 = 0x7
-       BPF_SOCK_OPS_RTO_CB                   = 0x8
-       BPF_SOCK_OPS_RETRANS_CB               = 0x9
-       BPF_SOCK_OPS_STATE_CB                 = 0xa
-       BPF_SOCK_OPS_TCP_LISTEN_CB            = 0xb
-       BPF_SOCK_OPS_RTT_CB                   = 0xc
-       BPF_TCP_ESTABLISHED                   = 0x1
-       BPF_TCP_SYN_SENT                      = 0x2
-       BPF_TCP_SYN_RECV                      = 0x3
-       BPF_TCP_FIN_WAIT1                     = 0x4
-       BPF_TCP_FIN_WAIT2                     = 0x5
-       BPF_TCP_TIME_WAIT                     = 0x6
-       BPF_TCP_CLOSE                         = 0x7
-       BPF_TCP_CLOSE_WAIT                    = 0x8
-       BPF_TCP_LAST_ACK                      = 0x9
-       BPF_TCP_LISTEN                        = 0xa
-       BPF_TCP_CLOSING                       = 0xb
-       BPF_TCP_NEW_SYN_RECV                  = 0xc
-       BPF_TCP_MAX_STATES                    = 0xd
-       BPF_FIB_LKUP_RET_SUCCESS              = 0x0
-       BPF_FIB_LKUP_RET_BLACKHOLE            = 0x1
-       BPF_FIB_LKUP_RET_UNREACHABLE          = 0x2
-       BPF_FIB_LKUP_RET_PROHIBIT             = 0x3
-       BPF_FIB_LKUP_RET_NOT_FWDED            = 0x4
-       BPF_FIB_LKUP_RET_FWD_DISABLED         = 0x5
-       BPF_FIB_LKUP_RET_UNSUPP_LWT           = 0x6
-       BPF_FIB_LKUP_RET_NO_NEIGH             = 0x7
-       BPF_FIB_LKUP_RET_FRAG_NEEDED          = 0x8
-       BPF_FD_TYPE_RAW_TRACEPOINT            = 0x0
-       BPF_FD_TYPE_TRACEPOINT                = 0x1
-       BPF_FD_TYPE_KPROBE                    = 0x2
-       BPF_FD_TYPE_KRETPROBE                 = 0x3
-       BPF_FD_TYPE_UPROBE                    = 0x4
-       BPF_FD_TYPE_URETPROBE                 = 0x5
+       BPF_REG_0                               = 0x0
+       BPF_REG_1                               = 0x1
+       BPF_REG_2                               = 0x2
+       BPF_REG_3                               = 0x3
+       BPF_REG_4                               = 0x4
+       BPF_REG_5                               = 0x5
+       BPF_REG_6                               = 0x6
+       BPF_REG_7                               = 0x7
+       BPF_REG_8                               = 0x8
+       BPF_REG_9                               = 0x9
+       BPF_REG_10                              = 0xa
+       BPF_MAP_CREATE                          = 0x0
+       BPF_MAP_LOOKUP_ELEM                     = 0x1
+       BPF_MAP_UPDATE_ELEM                     = 0x2
+       BPF_MAP_DELETE_ELEM                     = 0x3
+       BPF_MAP_GET_NEXT_KEY                    = 0x4
+       BPF_PROG_LOAD                           = 0x5
+       BPF_OBJ_PIN                             = 0x6
+       BPF_OBJ_GET                             = 0x7
+       BPF_PROG_ATTACH                         = 0x8
+       BPF_PROG_DETACH                         = 0x9
+       BPF_PROG_TEST_RUN                       = 0xa
+       BPF_PROG_GET_NEXT_ID                    = 0xb
+       BPF_MAP_GET_NEXT_ID                     = 0xc
+       BPF_PROG_GET_FD_BY_ID                   = 0xd
+       BPF_MAP_GET_FD_BY_ID                    = 0xe
+       BPF_OBJ_GET_INFO_BY_FD                  = 0xf
+       BPF_PROG_QUERY                          = 0x10
+       BPF_RAW_TRACEPOINT_OPEN                 = 0x11
+       BPF_BTF_LOAD                            = 0x12
+       BPF_BTF_GET_FD_BY_ID                    = 0x13
+       BPF_TASK_FD_QUERY                       = 0x14
+       BPF_MAP_LOOKUP_AND_DELETE_ELEM          = 0x15
+       BPF_MAP_FREEZE                          = 0x16
+       BPF_BTF_GET_NEXT_ID                     = 0x17
+       BPF_MAP_LOOKUP_BATCH                    = 0x18
+       BPF_MAP_LOOKUP_AND_DELETE_BATCH         = 0x19
+       BPF_MAP_UPDATE_BATCH                    = 0x1a
+       BPF_MAP_DELETE_BATCH                    = 0x1b
+       BPF_LINK_CREATE                         = 0x1c
+       BPF_LINK_UPDATE                         = 0x1d
+       BPF_MAP_TYPE_UNSPEC                     = 0x0
+       BPF_MAP_TYPE_HASH                       = 0x1
+       BPF_MAP_TYPE_ARRAY                      = 0x2
+       BPF_MAP_TYPE_PROG_ARRAY                 = 0x3
+       BPF_MAP_TYPE_PERF_EVENT_ARRAY           = 0x4
+       BPF_MAP_TYPE_PERCPU_HASH                = 0x5
+       BPF_MAP_TYPE_PERCPU_ARRAY               = 0x6
+       BPF_MAP_TYPE_STACK_TRACE                = 0x7
+       BPF_MAP_TYPE_CGROUP_ARRAY               = 0x8
+       BPF_MAP_TYPE_LRU_HASH                   = 0x9
+       BPF_MAP_TYPE_LRU_PERCPU_HASH            = 0xa
+       BPF_MAP_TYPE_LPM_TRIE                   = 0xb
+       BPF_MAP_TYPE_ARRAY_OF_MAPS              = 0xc
+       BPF_MAP_TYPE_HASH_OF_MAPS               = 0xd
+       BPF_MAP_TYPE_DEVMAP                     = 0xe
+       BPF_MAP_TYPE_SOCKMAP                    = 0xf
+       BPF_MAP_TYPE_CPUMAP                     = 0x10
+       BPF_MAP_TYPE_XSKMAP                     = 0x11
+       BPF_MAP_TYPE_SOCKHASH                   = 0x12
+       BPF_MAP_TYPE_CGROUP_STORAGE             = 0x13
+       BPF_MAP_TYPE_REUSEPORT_SOCKARRAY        = 0x14
+       BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE      = 0x15
+       BPF_MAP_TYPE_QUEUE                      = 0x16
+       BPF_MAP_TYPE_STACK                      = 0x17
+       BPF_MAP_TYPE_SK_STORAGE                 = 0x18
+       BPF_MAP_TYPE_DEVMAP_HASH                = 0x19
+       BPF_MAP_TYPE_STRUCT_OPS                 = 0x1a
+       BPF_PROG_TYPE_UNSPEC                    = 0x0
+       BPF_PROG_TYPE_SOCKET_FILTER             = 0x1
+       BPF_PROG_TYPE_KPROBE                    = 0x2
+       BPF_PROG_TYPE_SCHED_CLS                 = 0x3
+       BPF_PROG_TYPE_SCHED_ACT                 = 0x4
+       BPF_PROG_TYPE_TRACEPOINT                = 0x5
+       BPF_PROG_TYPE_XDP                       = 0x6
+       BPF_PROG_TYPE_PERF_EVENT                = 0x7
+       BPF_PROG_TYPE_CGROUP_SKB                = 0x8
+       BPF_PROG_TYPE_CGROUP_SOCK               = 0x9
+       BPF_PROG_TYPE_LWT_IN                    = 0xa
+       BPF_PROG_TYPE_LWT_OUT                   = 0xb
+       BPF_PROG_TYPE_LWT_XMIT                  = 0xc
+       BPF_PROG_TYPE_SOCK_OPS                  = 0xd
+       BPF_PROG_TYPE_SK_SKB                    = 0xe
+       BPF_PROG_TYPE_CGROUP_DEVICE             = 0xf
+       BPF_PROG_TYPE_SK_MSG                    = 0x10
+       BPF_PROG_TYPE_RAW_TRACEPOINT            = 0x11
+       BPF_PROG_TYPE_CGROUP_SOCK_ADDR          = 0x12
+       BPF_PROG_TYPE_LWT_SEG6LOCAL             = 0x13
+       BPF_PROG_TYPE_LIRC_MODE2                = 0x14
+       BPF_PROG_TYPE_SK_REUSEPORT              = 0x15
+       BPF_PROG_TYPE_FLOW_DISSECTOR            = 0x16
+       BPF_PROG_TYPE_CGROUP_SYSCTL             = 0x17
+       BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE   = 0x18
+       BPF_PROG_TYPE_CGROUP_SOCKOPT            = 0x19
+       BPF_PROG_TYPE_TRACING                   = 0x1a
+       BPF_PROG_TYPE_STRUCT_OPS                = 0x1b
+       BPF_PROG_TYPE_EXT                       = 0x1c
+       BPF_PROG_TYPE_LSM                       = 0x1d
+       BPF_CGROUP_INET_INGRESS                 = 0x0
+       BPF_CGROUP_INET_EGRESS                  = 0x1
+       BPF_CGROUP_INET_SOCK_CREATE             = 0x2
+       BPF_CGROUP_SOCK_OPS                     = 0x3
+       BPF_SK_SKB_STREAM_PARSER                = 0x4
+       BPF_SK_SKB_STREAM_VERDICT               = 0x5
+       BPF_CGROUP_DEVICE                       = 0x6
+       BPF_SK_MSG_VERDICT                      = 0x7
+       BPF_CGROUP_INET4_BIND                   = 0x8
+       BPF_CGROUP_INET6_BIND                   = 0x9
+       BPF_CGROUP_INET4_CONNECT                = 0xa
+       BPF_CGROUP_INET6_CONNECT                = 0xb
+       BPF_CGROUP_INET4_POST_BIND              = 0xc
+       BPF_CGROUP_INET6_POST_BIND              = 0xd
+       BPF_CGROUP_UDP4_SENDMSG                 = 0xe
+       BPF_CGROUP_UDP6_SENDMSG                 = 0xf
+       BPF_LIRC_MODE2                          = 0x10
+       BPF_FLOW_DISSECTOR                      = 0x11
+       BPF_CGROUP_SYSCTL                       = 0x12
+       BPF_CGROUP_UDP4_RECVMSG                 = 0x13
+       BPF_CGROUP_UDP6_RECVMSG                 = 0x14
+       BPF_CGROUP_GETSOCKOPT                   = 0x15
+       BPF_CGROUP_SETSOCKOPT                   = 0x16
+       BPF_TRACE_RAW_TP                        = 0x17
+       BPF_TRACE_FENTRY                        = 0x18
+       BPF_TRACE_FEXIT                         = 0x19
+       BPF_MODIFY_RETURN                       = 0x1a
+       BPF_LSM_MAC                             = 0x1b
+       BPF_ANY                                 = 0x0
+       BPF_NOEXIST                             = 0x1
+       BPF_EXIST                               = 0x2
+       BPF_F_LOCK                              = 0x4
+       BPF_F_NO_PREALLOC                       = 0x1
+       BPF_F_NO_COMMON_LRU                     = 0x2
+       BPF_F_NUMA_NODE                         = 0x4
+       BPF_F_RDONLY                            = 0x8
+       BPF_F_WRONLY                            = 0x10
+       BPF_F_STACK_BUILD_ID                    = 0x20
+       BPF_F_ZERO_SEED                         = 0x40
+       BPF_F_RDONLY_PROG                       = 0x80
+       BPF_F_WRONLY_PROG                       = 0x100
+       BPF_F_CLONE                             = 0x200
+       BPF_F_MMAPABLE                          = 0x400
+       BPF_STACK_BUILD_ID_EMPTY                = 0x0
+       BPF_STACK_BUILD_ID_VALID                = 0x1
+       BPF_STACK_BUILD_ID_IP                   = 0x2
+       BPF_F_RECOMPUTE_CSUM                    = 0x1
+       BPF_F_INVALIDATE_HASH                   = 0x2
+       BPF_F_HDR_FIELD_MASK                    = 0xf
+       BPF_F_PSEUDO_HDR                        = 0x10
+       BPF_F_MARK_MANGLED_0                    = 0x20
+       BPF_F_MARK_ENFORCE                      = 0x40
+       BPF_F_INGRESS                           = 0x1
+       BPF_F_TUNINFO_IPV6                      = 0x1
+       BPF_F_SKIP_FIELD_MASK                   = 0xff
+       BPF_F_USER_STACK                        = 0x100
+       BPF_F_FAST_STACK_CMP                    = 0x200
+       BPF_F_REUSE_STACKID                     = 0x400
+       BPF_F_USER_BUILD_ID                     = 0x800
+       BPF_F_ZERO_CSUM_TX                      = 0x2
+       BPF_F_DONT_FRAGMENT                     = 0x4
+       BPF_F_SEQ_NUMBER                        = 0x8
+       BPF_F_INDEX_MASK                        = 0xffffffff
+       BPF_F_CURRENT_CPU                       = 0xffffffff
+       BPF_F_CTXLEN_MASK                       = 0xfffff00000000
+       BPF_F_CURRENT_NETNS                     = -0x1
+       BPF_F_ADJ_ROOM_FIXED_GSO                = 0x1
+       BPF_F_ADJ_ROOM_ENCAP_L3_IPV4            = 0x2
+       BPF_F_ADJ_ROOM_ENCAP_L3_IPV6            = 0x4
+       BPF_F_ADJ_ROOM_ENCAP_L4_GRE             = 0x8
+       BPF_F_ADJ_ROOM_ENCAP_L4_UDP             = 0x10
+       BPF_ADJ_ROOM_ENCAP_L2_MASK              = 0xff
+       BPF_ADJ_ROOM_ENCAP_L2_SHIFT             = 0x38
+       BPF_F_SYSCTL_BASE_NAME                  = 0x1
+       BPF_SK_STORAGE_GET_F_CREATE             = 0x1
+       BPF_F_GET_BRANCH_RECORDS_SIZE           = 0x1
+       BPF_ADJ_ROOM_NET                        = 0x0
+       BPF_ADJ_ROOM_MAC                        = 0x1
+       BPF_HDR_START_MAC                       = 0x0
+       BPF_HDR_START_NET                       = 0x1
+       BPF_LWT_ENCAP_SEG6                      = 0x0
+       BPF_LWT_ENCAP_SEG6_INLINE               = 0x1
+       BPF_LWT_ENCAP_IP                        = 0x2
+       BPF_OK                                  = 0x0
+       BPF_DROP                                = 0x2
+       BPF_REDIRECT                            = 0x7
+       BPF_LWT_REROUTE                         = 0x80
+       BPF_SOCK_OPS_RTO_CB_FLAG                = 0x1
+       BPF_SOCK_OPS_RETRANS_CB_FLAG            = 0x2
+       BPF_SOCK_OPS_STATE_CB_FLAG              = 0x4
+       BPF_SOCK_OPS_RTT_CB_FLAG                = 0x8
+       BPF_SOCK_OPS_ALL_CB_FLAGS               = 0xf
+       BPF_SOCK_OPS_VOID                       = 0x0
+       BPF_SOCK_OPS_TIMEOUT_INIT               = 0x1
+       BPF_SOCK_OPS_RWND_INIT                  = 0x2
+       BPF_SOCK_OPS_TCP_CONNECT_CB             = 0x3
+       BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB      = 0x4
+       BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB     = 0x5
+       BPF_SOCK_OPS_NEEDS_ECN                  = 0x6
+       BPF_SOCK_OPS_BASE_RTT                   = 0x7
+       BPF_SOCK_OPS_RTO_CB                     = 0x8
+       BPF_SOCK_OPS_RETRANS_CB                 = 0x9
+       BPF_SOCK_OPS_STATE_CB                   = 0xa
+       BPF_SOCK_OPS_TCP_LISTEN_CB              = 0xb
+       BPF_SOCK_OPS_RTT_CB                     = 0xc
+       BPF_TCP_ESTABLISHED                     = 0x1
+       BPF_TCP_SYN_SENT                        = 0x2
+       BPF_TCP_SYN_RECV                        = 0x3
+       BPF_TCP_FIN_WAIT1                       = 0x4
+       BPF_TCP_FIN_WAIT2                       = 0x5
+       BPF_TCP_TIME_WAIT                       = 0x6
+       BPF_TCP_CLOSE                           = 0x7
+       BPF_TCP_CLOSE_WAIT                      = 0x8
+       BPF_TCP_LAST_ACK                        = 0x9
+       BPF_TCP_LISTEN                          = 0xa
+       BPF_TCP_CLOSING                         = 0xb
+       BPF_TCP_NEW_SYN_RECV                    = 0xc
+       BPF_TCP_MAX_STATES                      = 0xd
+       TCP_BPF_IW                              = 0x3e9
+       TCP_BPF_SNDCWND_CLAMP                   = 0x3ea
+       BPF_DEVCG_ACC_MKNOD                     = 0x1
+       BPF_DEVCG_ACC_READ                      = 0x2
+       BPF_DEVCG_ACC_WRITE                     = 0x4
+       BPF_DEVCG_DEV_BLOCK                     = 0x1
+       BPF_DEVCG_DEV_CHAR                      = 0x2
+       BPF_FIB_LOOKUP_DIRECT                   = 0x1
+       BPF_FIB_LOOKUP_OUTPUT                   = 0x2
+       BPF_FIB_LKUP_RET_SUCCESS                = 0x0
+       BPF_FIB_LKUP_RET_BLACKHOLE              = 0x1
+       BPF_FIB_LKUP_RET_UNREACHABLE            = 0x2
+       BPF_FIB_LKUP_RET_PROHIBIT               = 0x3
+       BPF_FIB_LKUP_RET_NOT_FWDED              = 0x4
+       BPF_FIB_LKUP_RET_FWD_DISABLED           = 0x5
+       BPF_FIB_LKUP_RET_UNSUPP_LWT             = 0x6
+       BPF_FIB_LKUP_RET_NO_NEIGH               = 0x7
+       BPF_FIB_LKUP_RET_FRAG_NEEDED            = 0x8
+       BPF_FD_TYPE_RAW_TRACEPOINT              = 0x0
+       BPF_FD_TYPE_TRACEPOINT                  = 0x1
+       BPF_FD_TYPE_KPROBE                      = 0x2
+       BPF_FD_TYPE_KRETPROBE                   = 0x3
+       BPF_FD_TYPE_UPROBE                      = 0x4
+       BPF_FD_TYPE_URETPROBE                   = 0x5
+       BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG     = 0x1
+       BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL = 0x2
+       BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP      = 0x4
 )
 
 const (
@@ -2200,7 +2279,7 @@ const (
        DEVLINK_CMD_DPIPE_ENTRIES_GET             = 0x20
        DEVLINK_CMD_DPIPE_HEADERS_GET             = 0x21
        DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET      = 0x22
-       DEVLINK_CMD_MAX                           = 0x44
+       DEVLINK_CMD_MAX                           = 0x48
        DEVLINK_PORT_TYPE_NOTSET                  = 0x0
        DEVLINK_PORT_TYPE_AUTO                    = 0x1
        DEVLINK_PORT_TYPE_ETH                     = 0x2
@@ -2280,7 +2359,7 @@ const (
        DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE     = 0x3c
        DEVLINK_ATTR_PAD                          = 0x3d
        DEVLINK_ATTR_ESWITCH_ENCAP_MODE           = 0x3e
-       DEVLINK_ATTR_MAX                          = 0x8c
+       DEVLINK_ATTR_MAX                          = 0x90
        DEVLINK_DPIPE_FIELD_MAPPING_TYPE_NONE     = 0x0
        DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX  = 0x1
        DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT      = 0x0
index d7771134158f162a0246acdfefa14471c33495ae..82076fb74ff94f82a23087caed1cfc90884a000a 100644 (file)
@@ -104,6 +104,35 @@ func (d *DLL) MustFindProc(name string) *Proc {
        return p
 }
 
+// FindProcByOrdinal searches DLL d for procedure by ordinal and returns *Proc
+// if found. It returns an error if search fails.
+func (d *DLL) FindProcByOrdinal(ordinal uintptr) (proc *Proc, err error) {
+       a, e := GetProcAddressByOrdinal(d.Handle, ordinal)
+       name := "#" + itoa(int(ordinal))
+       if e != nil {
+               return nil, &DLLError{
+                       Err:     e,
+                       ObjName: name,
+                       Msg:     "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(),
+               }
+       }
+       p := &Proc{
+               Dll:  d,
+               Name: name,
+               addr: a,
+       }
+       return p, nil
+}
+
+// MustFindProcByOrdinal is like FindProcByOrdinal but panics if search fails.
+func (d *DLL) MustFindProcByOrdinal(ordinal uintptr) *Proc {
+       p, e := d.FindProcByOrdinal(ordinal)
+       if e != nil {
+               panic(e)
+       }
+       return p
+}
+
 // Release unloads DLL d from memory.
 func (d *DLL) Release() (err error) {
        return FreeLibrary(d.Handle)
index f482a9fab3b33d7d5a5fc14325fe5da5e131fff2..92ac05ff4ea606ee76025c4004a2556599a6f02c 100644 (file)
@@ -8,7 +8,6 @@ package windows
 
 import (
        "syscall"
-       "unicode/utf16"
        "unsafe"
 )
 
@@ -40,17 +39,11 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) {
        defer DestroyEnvironmentBlock(block)
        blockp := uintptr(unsafe.Pointer(block))
        for {
-               entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(blockp))[:]
-               for i, v := range entry {
-                       if v == 0 {
-                               entry = entry[:i]
-                               break
-                       }
-               }
+               entry := UTF16PtrToString((*uint16)(unsafe.Pointer(blockp)))
                if len(entry) == 0 {
                        break
                }
-               env = append(env, string(utf16.Decode(entry)))
+               env = append(env, entry)
                blockp += 2 * (uintptr(len(entry)) + 1)
        }
        return env, nil
index f80a4204f097d884b94ccb2324b8694863d6877f..e409d76f0fde70d89f5c688630bc90b2c510afbd 100644 (file)
@@ -23,4 +23,9 @@ const (
        PAGE_EXECUTE_READ      = 0x20
        PAGE_EXECUTE_READWRITE = 0x40
        PAGE_EXECUTE_WRITECOPY = 0x80
+
+       QUOTA_LIMITS_HARDWS_MIN_DISABLE = 0x00000002
+       QUOTA_LIMITS_HARDWS_MIN_ENABLE  = 0x00000001
+       QUOTA_LIMITS_HARDWS_MAX_DISABLE = 0x00000008
+       QUOTA_LIMITS_HARDWS_MAX_ENABLE  = 0x00000004
 )
index 4b6eff1868bb36fd653bc7c981a441939d62d646..9e3c44a855708314dd1f2eb130e2cf48d36c9a8f 100644 (file)
@@ -7,6 +7,8 @@ package windows
 import (
        "syscall"
        "unsafe"
+
+       "golang.org/x/sys/internal/unsafeheader"
 )
 
 const (
@@ -1229,7 +1231,7 @@ func (sd *SECURITY_DESCRIPTOR) String() string {
                return ""
        }
        defer LocalFree(Handle(unsafe.Pointer(sddl)))
-       return UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(sddl))[:])
+       return UTF16PtrToString(sddl)
 }
 
 // ToAbsolute converts a self-relative security descriptor into an absolute one.
@@ -1307,9 +1309,17 @@ func (absoluteSD *SECURITY_DESCRIPTOR) ToSelfRelative() (selfRelativeSD *SECURIT
 }
 
 func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor() *SECURITY_DESCRIPTOR {
-       sdBytes := make([]byte, selfRelativeSD.Length())
-       copy(sdBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(selfRelativeSD))[:len(sdBytes)])
-       return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&sdBytes[0]))
+       sdLen := (int)(selfRelativeSD.Length())
+
+       var src []byte
+       h := (*unsafeheader.Slice)(unsafe.Pointer(&src))
+       h.Data = unsafe.Pointer(selfRelativeSD)
+       h.Len = sdLen
+       h.Cap = sdLen
+
+       dst := make([]byte, sdLen)
+       copy(dst, src)
+       return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0]))
 }
 
 // SecurityDescriptorFromString converts an SDDL string describing a security descriptor into a
@@ -1391,6 +1401,6 @@ func ACLFromEntries(explicitEntries []EXPLICIT_ACCESS, mergedACL *ACL) (acl *ACL
        }
        defer LocalFree(Handle(unsafe.Pointer(winHeapACL)))
        aclBytes := make([]byte, winHeapACL.aclSize)
-       copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes)])
+       copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes):len(aclBytes)])
        return (*ACL)(unsafe.Pointer(&aclBytes[0])), nil
 }
index 053d664d0b15fc7a40da79c0b2e0508779ee535e..62cf70e9f67021d4231cb0df7dea6b33bab519c2 100644 (file)
@@ -13,6 +13,8 @@ import (
        "time"
        "unicode/utf16"
        "unsafe"
+
+       "golang.org/x/sys/internal/unsafeheader"
 )
 
 type Handle uintptr
@@ -117,6 +119,32 @@ func UTF16PtrFromString(s string) (*uint16, error) {
        return &a[0], nil
 }
 
+// UTF16PtrToString takes a pointer to a UTF-16 sequence and returns the corresponding UTF-8 encoded string.
+// If the pointer is nil, this returns the empty string. This assumes that the UTF-16 sequence is terminated
+// at a zero word; if the zero word is not present, the program may crash.
+func UTF16PtrToString(p *uint16) string {
+       if p == nil {
+               return ""
+       }
+       if *p == 0 {
+               return ""
+       }
+
+       // Find NUL terminator.
+       n := 0
+       for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ {
+               ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p))
+       }
+
+       var s []uint16
+       h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
+       h.Data = unsafe.Pointer(p)
+       h.Len = n
+       h.Cap = n
+
+       return string(utf16.Decode(s))
+}
+
 func Getpagesize() int { return 4096 }
 
 // NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention.
@@ -280,6 +308,8 @@ func NewCallbackCDecl(fn interface{}) uintptr {
 //sys  GetProcessId(process Handle) (id uint32, err error)
 //sys  OpenThread(desiredAccess uint32, inheritHandle bool, threadId uint32) (handle Handle, err error)
 //sys  SetProcessPriorityBoost(process Handle, disable bool) (err error) = kernel32.SetProcessPriorityBoost
+//sys  GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32)
+//sys  SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error)
 
 // Volume Management Functions
 //sys  DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW
@@ -1181,7 +1211,12 @@ type IPv6Mreq struct {
        Interface uint32
 }
 
-func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, syscall.EWINDOWS }
+func GetsockoptInt(fd Handle, level, opt int) (int, error) {
+       v := int32(0)
+       l := int32(unsafe.Sizeof(v))
+       err := Getsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), &l)
+       return int(v), err
+}
 
 func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
        sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)}
@@ -1378,7 +1413,7 @@ func (t Token) KnownFolderPath(folderID *KNOWNFOLDERID, flags uint32) (string, e
                return "", err
        }
        defer CoTaskMemFree(unsafe.Pointer(p))
-       return UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:]), nil
+       return UTF16PtrToString(p), nil
 }
 
 // RtlGetVersion returns the version of the underlying operating system, ignoring
index 2aa4fa642a3d470baee77c0fa9818c3a89112984..8a562feed0d7e9a87d36ef2e41c4ab5a91e21686 100644 (file)
@@ -217,6 +217,8 @@ var (
        procGetProcessId                                         = modkernel32.NewProc("GetProcessId")
        procOpenThread                                           = modkernel32.NewProc("OpenThread")
        procSetProcessPriorityBoost                              = modkernel32.NewProc("SetProcessPriorityBoost")
+       procGetProcessWorkingSetSizeEx                           = modkernel32.NewProc("GetProcessWorkingSetSizeEx")
+       procSetProcessWorkingSetSizeEx                           = modkernel32.NewProc("SetProcessWorkingSetSizeEx")
        procDefineDosDeviceW                                     = modkernel32.NewProc("DefineDosDeviceW")
        procDeleteVolumeMountPointW                              = modkernel32.NewProc("DeleteVolumeMountPointW")
        procFindFirstVolumeW                                     = modkernel32.NewProc("FindFirstVolumeW")
@@ -2414,6 +2416,23 @@ func SetProcessPriorityBoost(process Handle, disable bool) (err error) {
        return
 }
 
+func GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32) {
+       syscall.Syscall6(procGetProcessWorkingSetSizeEx.Addr(), 4, uintptr(hProcess), uintptr(unsafe.Pointer(lpMinimumWorkingSetSize)), uintptr(unsafe.Pointer(lpMaximumWorkingSetSize)), uintptr(unsafe.Pointer(flags)), 0, 0)
+       return
+}
+
+func SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error) {
+       r1, _, e1 := syscall.Syscall6(procSetProcessWorkingSetSizeEx.Addr(), 4, uintptr(hProcess), uintptr(dwMinimumWorkingSetSize), uintptr(dwMaximumWorkingSetSize), uintptr(flags), 0, 0)
+       if r1 == 0 {
+               if e1 != 0 {
+                       err = errnoErr(e1)
+               } else {
+                       err = syscall.EINVAL
+               }
+       }
+       return
+}
+
 func DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) {
        r1, _, e1 := syscall.Syscall(procDefineDosDeviceW.Addr(), 3, uintptr(flags), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)))
        if r1 == 0 {
index cde2c20d3e8f3a5978e551cdd6b068048b4d54f5..77dbe1b5c8bd3687ef0ff594f7775af99188848d 100644 (file)
@@ -16,6 +16,7 @@ import (
        "google.golang.org/protobuf/internal/flags"
        "google.golang.org/protobuf/internal/pragma"
        "google.golang.org/protobuf/internal/set"
+       "google.golang.org/protobuf/internal/strs"
        "google.golang.org/protobuf/proto"
        pref "google.golang.org/protobuf/reflect/protoreflect"
        "google.golang.org/protobuf/reflect/protoregistry"
@@ -339,10 +340,10 @@ func (d decoder) unmarshalScalar(fd pref.FieldDescriptor) (pref.Value, error) {
 
        case pref.StringKind:
                if s, ok := tok.String(); ok {
-                       if utf8.ValidString(s) {
-                               return pref.ValueOfString(s), nil
+                       if strs.EnforceUTF8(fd) && !utf8.ValidString(s) {
+                               return pref.Value{}, d.newError(tok.Pos(), "contains invalid UTF-8")
                        }
-                       return pref.Value{}, d.newError(tok.Pos(), "contains invalid UTF-8")
+                       return pref.ValueOfString(s), nil
                }
 
        case pref.BytesKind:
index 83b65a66615193bdcf8003aaaecf6a94355f6133..dece229730b95052c476536a3ff3b014822e7edd 100644 (file)
@@ -18,6 +18,7 @@ import (
        "google.golang.org/protobuf/internal/flags"
        "google.golang.org/protobuf/internal/mapsort"
        "google.golang.org/protobuf/internal/pragma"
+       "google.golang.org/protobuf/internal/strs"
        "google.golang.org/protobuf/proto"
        pref "google.golang.org/protobuf/reflect/protoreflect"
        "google.golang.org/protobuf/reflect/protoregistry"
@@ -55,6 +56,15 @@ type MarshalOptions struct {
        // Indent can only be composed of space or tab characters.
        Indent string
 
+       // EmitASCII specifies whether to format strings and bytes as ASCII only
+       // as opposed to using UTF-8 encoding when possible.
+       EmitASCII bool
+
+       // allowInvalidUTF8 specifies whether to permit the encoding of strings
+       // with invalid UTF-8. This is unexported as it is intended to only
+       // be specified by the Format method.
+       allowInvalidUTF8 bool
+
        // AllowPartial allows messages that have missing required fields to marshal
        // without returning an error. If AllowPartial is false (the default),
        // Marshal will return error if there are any missing required fields.
@@ -81,6 +91,7 @@ func (o MarshalOptions) Format(m proto.Message) string {
        if m == nil || !m.ProtoReflect().IsValid() {
                return "<nil>" // invalid syntax, but okay since this is for debugging
        }
+       o.allowInvalidUTF8 = true
        o.AllowPartial = true
        o.EmitUnknown = true
        b, _ := o.Marshal(m)
@@ -91,7 +102,6 @@ func (o MarshalOptions) Format(m proto.Message) string {
 // MarshalOptions object. Do not depend on the output being stable. It may
 // change over time across different versions of the program.
 func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
-       const outputASCII = false
        var delims = [2]byte{'{', '}'}
 
        if o.Multiline && o.Indent == "" {
@@ -101,11 +111,17 @@ func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
                o.Resolver = protoregistry.GlobalTypes
        }
 
-       internalEnc, err := text.NewEncoder(o.Indent, delims, outputASCII)
+       internalEnc, err := text.NewEncoder(o.Indent, delims, o.EmitASCII)
        if err != nil {
                return nil, err
        }
 
+       // Treat nil message interface as an empty message,
+       // in which case there is nothing to output.
+       if m == nil {
+               return []byte{}, nil
+       }
+
        enc := encoder{internalEnc, o}
        err = enc.marshalMessage(m.ProtoReflect(), false)
        if err != nil {
@@ -209,7 +225,7 @@ func (e encoder) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error
 
        case pref.StringKind:
                s := val.String()
-               if !utf8.ValidString(s) {
+               if !e.opts.allowInvalidUTF8 && strs.EnforceUTF8(fd) && !utf8.ValidString(s) {
                        return errors.InvalidUTF8(string(fd.FullName()))
                }
                e.WriteString(s)
index 4cb8d6dfd44a6f4c601cc8f5596349e3ae9062fb..e7af0fe0de2f6a8e105b84c6dc96221ed09b912d 100644 (file)
@@ -106,7 +106,7 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string {
 var descriptorAccessors = map[reflect.Type][]string{
        reflect.TypeOf((*pref.FileDescriptor)(nil)).Elem():      {"Path", "Package", "Imports", "Messages", "Enums", "Extensions", "Services"},
        reflect.TypeOf((*pref.MessageDescriptor)(nil)).Elem():   {"IsMapEntry", "Fields", "Oneofs", "ReservedNames", "ReservedRanges", "RequiredNumbers", "ExtensionRanges", "Messages", "Enums", "Extensions"},
-       reflect.TypeOf((*pref.FieldDescriptor)(nil)).Elem():     {"Number", "Cardinality", "Kind", "HasJSONName", "JSONName", "IsPacked", "IsExtension", "IsWeak", "IsList", "IsMap", "MapKey", "MapValue", "HasDefault", "Default", "ContainingOneof", "ContainingMessage", "Message", "Enum"},
+       reflect.TypeOf((*pref.FieldDescriptor)(nil)).Elem():     {"Number", "Cardinality", "Kind", "HasJSONName", "JSONName", "HasPresence", "IsExtension", "IsPacked", "IsWeak", "IsList", "IsMap", "MapKey", "MapValue", "HasDefault", "Default", "ContainingOneof", "ContainingMessage", "Message", "Enum"},
        reflect.TypeOf((*pref.OneofDescriptor)(nil)).Elem():     {"Fields"}, // not directly used; must keep in sync with formatDescOpt
        reflect.TypeOf((*pref.EnumDescriptor)(nil)).Elem():      {"Values", "ReservedNames", "ReservedRanges"},
        reflect.TypeOf((*pref.EnumValueDescriptor)(nil)).Elem(): {"Number"},
index 16295154938b99155f6b4c14696aa50c9dcd0d63..6e37b59e92276391c0036b4d0acf45adf50eb125 100644 (file)
@@ -61,16 +61,17 @@ const (
 
 // Field numbers for google.protobuf.FieldDescriptorProto.
 const (
-       FieldDescriptorProto_Name         = 1  // optional string
-       FieldDescriptorProto_Number       = 3  // optional int32
-       FieldDescriptorProto_Label        = 4  // optional google.protobuf.FieldDescriptorProto.Label
-       FieldDescriptorProto_Type         = 5  // optional google.protobuf.FieldDescriptorProto.Type
-       FieldDescriptorProto_TypeName     = 6  // optional string
-       FieldDescriptorProto_Extendee     = 2  // optional string
-       FieldDescriptorProto_DefaultValue = 7  // optional string
-       FieldDescriptorProto_OneofIndex   = 9  // optional int32
-       FieldDescriptorProto_JsonName     = 10 // optional string
-       FieldDescriptorProto_Options      = 8  // optional google.protobuf.FieldOptions
+       FieldDescriptorProto_Name           = 1  // optional string
+       FieldDescriptorProto_Number         = 3  // optional int32
+       FieldDescriptorProto_Label          = 4  // optional google.protobuf.FieldDescriptorProto.Label
+       FieldDescriptorProto_Type           = 5  // optional google.protobuf.FieldDescriptorProto.Type
+       FieldDescriptorProto_TypeName       = 6  // optional string
+       FieldDescriptorProto_Extendee       = 2  // optional string
+       FieldDescriptorProto_DefaultValue   = 7  // optional string
+       FieldDescriptorProto_OneofIndex     = 9  // optional int32
+       FieldDescriptorProto_JsonName       = 10 // optional string
+       FieldDescriptorProto_Options        = 8  // optional google.protobuf.FieldOptions
+       FieldDescriptorProto_Proto3Optional = 17 // optional bool
 )
 
 // Field numbers for google.protobuf.OneofDescriptorProto.
index 1cb2d74fc6cfa00524798b9c12b7659e1679ee84..517c4e2a041a8ea72b21ac653e969ffa0314f82c 100644 (file)
@@ -30,9 +30,9 @@ func Less(a, b protoreflect.FieldDescriptor) bool {
                        return a.Number() < b.Number()
                }
                return oa.Index() < ob.Index()
-       case oa != nil:
+       case oa != nil && !oa.IsSynthetic():
                return false
-       case ob != nil:
+       case ob != nil && !ob.IsSynthetic():
                return true
        default:
                return a.Number() < b.Number()
index a9fe07c216e190a6fc5135c575d6b8739fb69fd3..2540befd64596d1b5c5e5de8210b2a435a44f615 100644 (file)
@@ -77,7 +77,7 @@ func (fd *File) Enums() pref.EnumDescriptors           { return &fd.L1.Enums }
 func (fd *File) Messages() pref.MessageDescriptors     { return &fd.L1.Messages }
 func (fd *File) Extensions() pref.ExtensionDescriptors { return &fd.L1.Extensions }
 func (fd *File) Services() pref.ServiceDescriptors     { return &fd.L1.Services }
-func (fd *File) SourceLocations() pref.SourceLocations { return &fd.L2.Locations }
+func (fd *File) SourceLocations() pref.SourceLocations { return &fd.lazyInit().Locations }
 func (fd *File) Format(s fmt.State, r rune)            { descfmt.FormatDesc(s, r, fd) }
 func (fd *File) ProtoType(pref.FileDescriptor)         {}
 func (fd *File) ProtoInternal(pragma.DoNotImplement)   {}
@@ -202,20 +202,21 @@ type (
                L1 FieldL1
        }
        FieldL1 struct {
-               Options         func() pref.ProtoMessage
-               Number          pref.FieldNumber
-               Cardinality     pref.Cardinality // must be consistent with Message.RequiredNumbers
-               Kind            pref.Kind
-               JSONName        jsonName
-               IsWeak          bool // promoted from google.protobuf.FieldOptions
-               HasPacked       bool // promoted from google.protobuf.FieldOptions
-               IsPacked        bool // promoted from google.protobuf.FieldOptions
-               HasEnforceUTF8  bool // promoted from google.protobuf.FieldOptions
-               EnforceUTF8     bool // promoted from google.protobuf.FieldOptions
-               Default         defaultValue
-               ContainingOneof pref.OneofDescriptor // must be consistent with Message.Oneofs.Fields
-               Enum            pref.EnumDescriptor
-               Message         pref.MessageDescriptor
+               Options          func() pref.ProtoMessage
+               Number           pref.FieldNumber
+               Cardinality      pref.Cardinality // must be consistent with Message.RequiredNumbers
+               Kind             pref.Kind
+               JSONName         jsonName
+               IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
+               IsWeak           bool // promoted from google.protobuf.FieldOptions
+               HasPacked        bool // promoted from google.protobuf.FieldOptions
+               IsPacked         bool // promoted from google.protobuf.FieldOptions
+               HasEnforceUTF8   bool // promoted from google.protobuf.FieldOptions
+               EnforceUTF8      bool // promoted from google.protobuf.FieldOptions
+               Default          defaultValue
+               ContainingOneof  pref.OneofDescriptor // must be consistent with Message.Oneofs.Fields
+               Enum             pref.EnumDescriptor
+               Message          pref.MessageDescriptor
        }
 
        Oneof struct {
@@ -277,6 +278,12 @@ func (fd *Field) Cardinality() pref.Cardinality { return fd.L1.Cardinality }
 func (fd *Field) Kind() pref.Kind               { return fd.L1.Kind }
 func (fd *Field) HasJSONName() bool             { return fd.L1.JSONName.has }
 func (fd *Field) JSONName() string              { return fd.L1.JSONName.get(fd) }
+func (fd *Field) HasPresence() bool {
+       return fd.L1.Cardinality != pref.Repeated && (fd.L0.ParentFile.L1.Syntax == pref.Proto2 || fd.L1.Message != nil || fd.L1.ContainingOneof != nil)
+}
+func (fd *Field) HasOptionalKeyword() bool {
+       return (fd.L0.ParentFile.L1.Syntax == pref.Proto2 && fd.L1.Cardinality == pref.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional
+}
 func (fd *Field) IsPacked() bool {
        if !fd.L1.HasPacked && fd.L0.ParentFile.L1.Syntax != pref.Proto2 && fd.L1.Cardinality == pref.Repeated {
                switch fd.L1.Kind {
@@ -338,6 +345,9 @@ func (fd *Field) EnforceUTF8() bool {
        return fd.L0.ParentFile.L1.Syntax == pref.Proto3
 }
 
+func (od *Oneof) IsSynthetic() bool {
+       return od.L0.ParentFile.L1.Syntax == pref.Proto3 && len(od.L1.Fields.List) == 1 && od.L1.Fields.List[0].HasOptionalKeyword()
+}
 func (od *Oneof) Options() pref.ProtoMessage {
        if f := od.L1.Options; f != nil {
                return f()
@@ -361,12 +371,13 @@ type (
                Kind        pref.Kind
        }
        ExtensionL2 struct {
-               Options  func() pref.ProtoMessage
-               JSONName jsonName
-               IsPacked bool // promoted from google.protobuf.FieldOptions
-               Default  defaultValue
-               Enum     pref.EnumDescriptor
-               Message  pref.MessageDescriptor
+               Options          func() pref.ProtoMessage
+               JSONName         jsonName
+               IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
+               IsPacked         bool // promoted from google.protobuf.FieldOptions
+               Default          defaultValue
+               Enum             pref.EnumDescriptor
+               Message          pref.MessageDescriptor
        }
 )
 
@@ -376,11 +387,15 @@ func (xd *Extension) Options() pref.ProtoMessage {
        }
        return descopts.Field
 }
-func (xd *Extension) Number() pref.FieldNumber                   { return xd.L1.Number }
-func (xd *Extension) Cardinality() pref.Cardinality              { return xd.L1.Cardinality }
-func (xd *Extension) Kind() pref.Kind                            { return xd.L1.Kind }
-func (xd *Extension) HasJSONName() bool                          { return xd.lazyInit().JSONName.has }
-func (xd *Extension) JSONName() string                           { return xd.lazyInit().JSONName.get(xd) }
+func (xd *Extension) Number() pref.FieldNumber      { return xd.L1.Number }
+func (xd *Extension) Cardinality() pref.Cardinality { return xd.L1.Cardinality }
+func (xd *Extension) Kind() pref.Kind               { return xd.L1.Kind }
+func (xd *Extension) HasJSONName() bool             { return xd.lazyInit().JSONName.has }
+func (xd *Extension) JSONName() string              { return xd.lazyInit().JSONName.get(xd) }
+func (xd *Extension) HasPresence() bool             { return xd.L1.Cardinality != pref.Repeated }
+func (xd *Extension) HasOptionalKeyword() bool {
+       return (xd.L0.ParentFile.L1.Syntax == pref.Proto2 && xd.L1.Cardinality == pref.Optional) || xd.lazyInit().IsProto3Optional
+}
 func (xd *Extension) IsPacked() bool                             { return xd.lazyInit().IsPacked }
 func (xd *Extension) IsExtension() bool                          { return true }
 func (xd *Extension) IsWeak() bool                               { return false }
@@ -592,7 +607,7 @@ func (dv *defaultValue) get(fd pref.FieldDescriptor) pref.Value {
                // TODO: Avoid panic if we're running with the race detector
                // and instead spawn a goroutine that periodically resets
                // this value back to the original to induce a race.
-               panic("detected mutation on the default bytes")
+               panic(fmt.Sprintf("detected mutation on the default bytes for %v", fd.FullName()))
        }
        return dv.val
 }
index cdf3164686367da2e0a6bb48319cb553a23e94f4..bc215944a32d7dc6ae6a69ed5fa2e9d9528e094d 100644 (file)
@@ -441,6 +441,8 @@ func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Des
                                        panic("oneof type already set")
                                }
                                fd.L1.ContainingOneof = od
+                       case fieldnum.FieldDescriptorProto_Proto3Optional:
+                               fd.L1.IsProto3Optional = protowire.DecodeBool(v)
                        }
                case protowire.BytesType:
                        v, m := protowire.ConsumeBytes(b)
@@ -537,6 +539,13 @@ func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) {
                num, typ, n := protowire.ConsumeTag(b)
                b = b[n:]
                switch typ {
+               case protowire.VarintType:
+                       v, m := protowire.ConsumeVarint(b)
+                       b = b[m:]
+                       switch num {
+                       case fieldnum.FieldDescriptorProto_Proto3Optional:
+                               xd.L2.IsProto3Optional = protowire.DecodeBool(v)
+                       }
                case protowire.BytesType:
                        v, m := protowire.ConsumeBytes(b)
                        b = b[m:]
index 2c43b11734246de98283517438abdb69ba366b5f..ff198d0a153b7a87a0f425b2f1e05c6284cd0368 100644 (file)
@@ -5078,6 +5078,46 @@ var coderStringPtr = pointerCoderFuncs{
        merge:     mergeStringPtr,
 }
 
+// appendStringPtrValidateUTF8 wire encodes a *string pointer as a String.
+// It panics if the pointer is nil.
+func appendStringPtrValidateUTF8(b []byte, p pointer, f *coderFieldInfo, _ marshalOptions) ([]byte, error) {
+       v := **p.StringPtr()
+       b = protowire.AppendVarint(b, f.wiretag)
+       b = protowire.AppendString(b, v)
+       if !utf8.ValidString(v) {
+               return b, errInvalidUTF8{}
+       }
+       return b, nil
+}
+
+// consumeStringPtrValidateUTF8 wire decodes a *string pointer as a String.
+func consumeStringPtrValidateUTF8(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
+       if wtyp != protowire.BytesType {
+               return out, errUnknown
+       }
+       v, n := protowire.ConsumeString(b)
+       if n < 0 {
+               return out, protowire.ParseError(n)
+       }
+       if !utf8.ValidString(v) {
+               return out, errInvalidUTF8{}
+       }
+       vp := p.StringPtr()
+       if *vp == nil {
+               *vp = new(string)
+       }
+       **vp = v
+       out.n = n
+       return out, nil
+}
+
+var coderStringPtrValidateUTF8 = pointerCoderFuncs{
+       size:      sizeStringPtr,
+       marshal:   appendStringPtrValidateUTF8,
+       unmarshal: consumeStringPtrValidateUTF8,
+       merge:     mergeStringPtr,
+}
+
 // sizeStringSlice returns the size of wire encoding a []string pointer as a repeated String.
 func sizeStringSlice(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
        s := *p.StringSlice()
index 370ec65a20b316b7ab266682330c826bcb4deb53..0e176d565d4042ff737944526e9e228a8656c04a 100644 (file)
@@ -53,11 +53,13 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
 
        mi.coderFields = make(map[protowire.Number]*coderFieldInfo)
        fields := mi.Desc.Fields()
+       preallocFields := make([]coderFieldInfo, fields.Len())
        for i := 0; i < fields.Len(); i++ {
                fd := fields.Get(i)
 
                fs := si.fieldsByNumber[fd.Number()]
-               if fd.ContainingOneof() != nil {
+               isOneof := fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic()
+               if isOneof {
                        fs = si.oneofsByName[fd.ContainingOneof().Name()]
                }
                ft := fs.Type
@@ -71,7 +73,7 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
                var funcs pointerCoderFuncs
                var childMessage *MessageInfo
                switch {
-               case fd.ContainingOneof() != nil:
+               case isOneof:
                        fieldOffset = offsetOf(fs, mi.Exporter)
                case fd.IsWeak():
                        fieldOffset = si.weakOffset
@@ -80,7 +82,8 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
                        fieldOffset = offsetOf(fs, mi.Exporter)
                        childMessage, funcs = fieldCoder(fd, ft)
                }
-               cf := &coderFieldInfo{
+               cf := &preallocFields[i]
+               *cf = coderFieldInfo{
                        num:        fd.Number(),
                        offset:     fieldOffset,
                        wiretag:    wiretag,
@@ -89,17 +92,16 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
                        funcs:      funcs,
                        mi:         childMessage,
                        validation: newFieldValidationInfo(mi, si, fd, ft),
-                       isPointer: (fd.Cardinality() == pref.Repeated ||
-                               fd.Kind() == pref.MessageKind ||
-                               fd.Kind() == pref.GroupKind ||
-                               fd.Syntax() != pref.Proto3),
+                       isPointer:  fd.Cardinality() == pref.Repeated || fd.HasPresence(),
                        isRequired: fd.Cardinality() == pref.Required,
                }
                mi.orderedCoderFields = append(mi.orderedCoderFields, cf)
                mi.coderFields[cf.num] = cf
        }
        for i, oneofs := 0, mi.Desc.Oneofs(); i < oneofs.Len(); i++ {
-               mi.initOneofFieldCoders(oneofs.Get(i), si)
+               if od := oneofs.Get(i); !od.IsSynthetic() {
+                       mi.initOneofFieldCoders(od, si)
+               }
        }
        if messageset.IsMessageSet(mi.Desc) {
                if !mi.extensionOffset.IsValid() {
@@ -123,7 +125,7 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) {
        }
        mi.denseCoderFields = make([]*coderFieldInfo, maxDense+1)
        for _, cf := range mi.orderedCoderFields {
-               if int(cf.num) > len(mi.denseCoderFields) {
+               if int(cf.num) >= len(mi.denseCoderFields) {
                        break
                }
                mi.denseCoderFields[cf.num] = cf
index c934c8d3ca8d2d883c366e2bec0e82bfe9e71435..e89971238879f2bfb7e6229257b065c4737912ed 100644 (file)
@@ -338,6 +338,9 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointer
                                return nil, coderDoublePtr
                        }
                case pref.StringKind:
+                       if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) {
+                               return nil, coderStringPtrValidateUTF8
+                       }
                        if ft.Kind() == reflect.String {
                                return nil, coderStringPtr
                        }
index 9fc384a7a584cfff82538e764d76d5ae0323c8a9..36a90dff381644456a5abd378e0fb5912d9cd3ef 100644 (file)
@@ -162,7 +162,7 @@ func (c *boolConverter) IsValidPB(v pref.Value) bool {
        return ok
 }
 func (c *boolConverter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 func (c *boolConverter) New() pref.Value  { return c.def }
 func (c *boolConverter) Zero() pref.Value { return c.def }
@@ -186,7 +186,7 @@ func (c *int32Converter) IsValidPB(v pref.Value) bool {
        return ok
 }
 func (c *int32Converter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 func (c *int32Converter) New() pref.Value  { return c.def }
 func (c *int32Converter) Zero() pref.Value { return c.def }
@@ -210,7 +210,7 @@ func (c *int64Converter) IsValidPB(v pref.Value) bool {
        return ok
 }
 func (c *int64Converter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 func (c *int64Converter) New() pref.Value  { return c.def }
 func (c *int64Converter) Zero() pref.Value { return c.def }
@@ -234,7 +234,7 @@ func (c *uint32Converter) IsValidPB(v pref.Value) bool {
        return ok
 }
 func (c *uint32Converter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 func (c *uint32Converter) New() pref.Value  { return c.def }
 func (c *uint32Converter) Zero() pref.Value { return c.def }
@@ -258,7 +258,7 @@ func (c *uint64Converter) IsValidPB(v pref.Value) bool {
        return ok
 }
 func (c *uint64Converter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 func (c *uint64Converter) New() pref.Value  { return c.def }
 func (c *uint64Converter) Zero() pref.Value { return c.def }
@@ -282,7 +282,7 @@ func (c *float32Converter) IsValidPB(v pref.Value) bool {
        return ok
 }
 func (c *float32Converter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 func (c *float32Converter) New() pref.Value  { return c.def }
 func (c *float32Converter) Zero() pref.Value { return c.def }
@@ -306,7 +306,7 @@ func (c *float64Converter) IsValidPB(v pref.Value) bool {
        return ok
 }
 func (c *float64Converter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 func (c *float64Converter) New() pref.Value  { return c.def }
 func (c *float64Converter) Zero() pref.Value { return c.def }
@@ -336,7 +336,7 @@ func (c *stringConverter) IsValidPB(v pref.Value) bool {
        return ok
 }
 func (c *stringConverter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 func (c *stringConverter) New() pref.Value  { return c.def }
 func (c *stringConverter) Zero() pref.Value { return c.def }
@@ -363,7 +363,7 @@ func (c *bytesConverter) IsValidPB(v pref.Value) bool {
        return ok
 }
 func (c *bytesConverter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 func (c *bytesConverter) New() pref.Value  { return c.def }
 func (c *bytesConverter) Zero() pref.Value { return c.def }
@@ -400,7 +400,7 @@ func (c *enumConverter) IsValidPB(v pref.Value) bool {
 }
 
 func (c *enumConverter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 
 func (c *enumConverter) New() pref.Value {
@@ -455,7 +455,7 @@ func (c *messageConverter) IsValidPB(v pref.Value) bool {
 }
 
 func (c *messageConverter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 
 func (c *messageConverter) New() pref.Value {
index fe9384aba3fd5ef782e5f30a760c0c606e7c3d0a..6fccab520e59a4e55f76c3e14a02f5b748a6d6b4 100644 (file)
@@ -22,7 +22,7 @@ func newListConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
 }
 
 type listConverter struct {
-       goType reflect.Type
+       goType reflect.Type // []T
        c      Converter
 }
 
@@ -48,11 +48,11 @@ func (c *listConverter) IsValidPB(v pref.Value) bool {
        if !ok {
                return false
        }
-       return list.v.Type().Elem() == c.goType && list.IsValid()
+       return list.v.Type().Elem() == c.goType
 }
 
 func (c *listConverter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 
 func (c *listConverter) New() pref.Value {
@@ -64,7 +64,7 @@ func (c *listConverter) Zero() pref.Value {
 }
 
 type listPtrConverter struct {
-       goType reflect.Type
+       goType reflect.Type // *[]T
        c      Converter
 }
 
@@ -88,7 +88,7 @@ func (c *listPtrConverter) IsValidPB(v pref.Value) bool {
 }
 
 func (c *listPtrConverter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 
 func (c *listPtrConverter) New() pref.Value {
index 3ef36d3f23cf88d8206bcc8a0f5f9a77c2180527..de06b2593f89ac7ce22b66a1fadeec7b0ccee030 100644 (file)
@@ -12,7 +12,7 @@ import (
 )
 
 type mapConverter struct {
-       goType           reflect.Type
+       goType           reflect.Type // map[K]V
        keyConv, valConv Converter
 }
 
@@ -43,11 +43,11 @@ func (c *mapConverter) IsValidPB(v pref.Value) bool {
        if !ok {
                return false
        }
-       return mapv.v.Type() == c.goType && mapv.IsValid()
+       return mapv.v.Type() == c.goType
 }
 
 func (c *mapConverter) IsValidGo(v reflect.Value) bool {
-       return v.Type() == c.goType
+       return v.IsValid() && v.Type() == c.goType
 }
 
 func (c *mapConverter) New() pref.Value {
index 94f45725f054b57e9da893bc57abaa499b00e1a3..c3d741c2f0c55a2a935dc7a0732fc08144bd0157 100644 (file)
@@ -7,14 +7,12 @@ package impl
 import (
        "encoding/binary"
        "encoding/json"
-       "fmt"
        "hash/crc32"
        "math"
        "reflect"
 
        "google.golang.org/protobuf/internal/errors"
        pref "google.golang.org/protobuf/reflect/protoreflect"
-       "google.golang.org/protobuf/reflect/protoregistry"
        piface "google.golang.org/protobuf/runtime/protoiface"
 )
 
@@ -92,13 +90,3 @@ func (Export) CompressGZIP(in []byte) (out []byte) {
        out = append(out, gzipFooter[:]...)
        return out
 }
-
-// WeakNil returns a typed nil pointer to a concrete message.
-// It panics if the message is not linked into the binary.
-func (Export) WeakNil(s pref.FullName) piface.MessageV1 {
-       mt, err := protoregistry.GlobalTypes.FindMessageByName(s)
-       if err != nil {
-               panic(fmt.Sprintf("weak message %v is not linked in", s))
-       }
-       return mt.Zero().Interface().(piface.MessageV1)
-}
index 93c318f9eacaf8ca39e402e34f4fdd2d7706d052..61757ce50a7811ba4c01de5c5e524dfed4134dd1 100644 (file)
@@ -155,6 +155,8 @@ func (x placeholderExtension) Cardinality() pref.Cardinality              { retu
 func (x placeholderExtension) Kind() pref.Kind                            { return 0 }
 func (x placeholderExtension) HasJSONName() bool                          { return false }
 func (x placeholderExtension) JSONName() string                           { return "" }
+func (x placeholderExtension) HasPresence() bool                          { return false }
+func (x placeholderExtension) HasOptionalKeyword() bool                   { return false }
 func (x placeholderExtension) IsExtension() bool                          { return true }
 func (x placeholderExtension) IsWeak() bool                               { return false }
 func (x placeholderExtension) IsPacked() bool                             { return false }
index c1d890233c986ded88dda10de2cab43ee8f74e01..7dd994bd95deea9308abe3ad98a90ddd754c4f0c 100644 (file)
@@ -15,7 +15,6 @@ import (
        "google.golang.org/protobuf/internal/genname"
        "google.golang.org/protobuf/reflect/protoreflect"
        pref "google.golang.org/protobuf/reflect/protoreflect"
-       piface "google.golang.org/protobuf/runtime/protoiface"
 )
 
 // MessageInfo provides protobuf related functionality for a given Go type
@@ -109,7 +108,7 @@ func (mi *MessageInfo) getPointer(m pref.Message) (p pointer, ok bool) {
 
 type (
        SizeCache       = int32
-       WeakFields      = map[int32]piface.MessageV1
+       WeakFields      = map[int32]protoreflect.ProtoMessage
        UnknownFields   = []byte
        ExtensionFields = map[int32]ExtensionField
 )
index aac55ee8d803a0a989d51b57dbab4b51afff2053..0f4b8db760aa98977cd66e8c27e4a85c7a7e3c7b 100644 (file)
@@ -53,7 +53,7 @@ func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
                fs := si.fieldsByNumber[fd.Number()]
                var fi fieldInfo
                switch {
-               case fd.ContainingOneof() != nil:
+               case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic():
                        fi = fieldInfoForOneof(fd, si.oneofsByName[fd.ContainingOneof().Name()], mi.Exporter, si.oneofWrappersByNumber[fd.Number()])
                case fd.IsMap():
                        fi = fieldInfoForMap(fd, fs, mi.Exporter)
@@ -72,7 +72,7 @@ func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
        mi.oneofs = map[pref.Name]*oneofInfo{}
        for i := 0; i < md.Oneofs().Len(); i++ {
                od := md.Oneofs().Get(i)
-               mi.oneofs[od.Name()] = makeOneofInfo(od, si.oneofsByName[od.Name()], mi.Exporter, si.oneofWrappersByType)
+               mi.oneofs[od.Name()] = makeOneofInfo(od, si, mi.Exporter)
        }
 
        mi.denseFields = make([]*fieldInfo, fds.Len()*2)
@@ -84,7 +84,7 @@ func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
 
        for i := 0; i < fds.Len(); {
                fd := fds.Get(i)
-               if od := fd.ContainingOneof(); od != nil {
+               if od := fd.ContainingOneof(); od != nil && !od.IsSynthetic() {
                        mi.rangeInfos = append(mi.rangeInfos, mi.oneofs[od.Name()])
                        i += od.Fields().Len()
                } else {
@@ -170,6 +170,8 @@ func (m *extensionMap) Has(xt pref.ExtensionType) (ok bool) {
                return x.Value().List().Len() > 0
        case xd.IsMap():
                return x.Value().Map().Len() > 0
+       case xd.Message() != nil:
+               return x.Value().Message().IsValid()
        }
        return true
 }
@@ -186,15 +188,28 @@ func (m *extensionMap) Get(xt pref.ExtensionType) pref.Value {
        return xt.Zero()
 }
 func (m *extensionMap) Set(xt pref.ExtensionType, v pref.Value) {
-       if !xt.IsValidValue(v) {
+       xd := xt.TypeDescriptor()
+       isValid := true
+       switch {
+       case !xt.IsValidValue(v):
+               isValid = false
+       case xd.IsList():
+               isValid = v.List().IsValid()
+       case xd.IsMap():
+               isValid = v.Map().IsValid()
+       case xd.Message() != nil:
+               isValid = v.Message().IsValid()
+       }
+       if !isValid {
                panic(fmt.Sprintf("%v: assigning invalid value", xt.TypeDescriptor().FullName()))
        }
+
        if *m == nil {
                *m = make(map[int32]ExtensionField)
        }
        var x ExtensionField
        x.Set(xt, v)
-       (*m)[int32(xt.TypeDescriptor().Number())] = x
+       (*m)[int32(xd.Number())] = x
 }
 func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value {
        xd := xt.TypeDescriptor()
@@ -323,24 +338,27 @@ func (mi *MessageInfo) checkField(fd pref.FieldDescriptor) (*fieldInfo, pref.Ext
        }
        if fi != nil {
                if fi.fieldDesc != fd {
-                       panic("mismatching field descriptor")
+                       if got, want := fd.FullName(), fi.fieldDesc.FullName(); got != want {
+                               panic(fmt.Sprintf("mismatching field: got %v, want %v", got, want))
+                       }
+                       panic(fmt.Sprintf("mismatching field: %v", fd.FullName()))
                }
                return fi, nil
        }
 
        if fd.IsExtension() {
-               if fd.ContainingMessage().FullName() != mi.Desc.FullName() {
+               if got, want := fd.ContainingMessage().FullName(), mi.Desc.FullName(); got != want {
                        // TODO: Should this be exact containing message descriptor match?
-                       panic("mismatching containing message")
+                       panic(fmt.Sprintf("extension %v has mismatching containing message: got %v, want %v", fd.FullName(), got, want))
                }
                if !mi.Desc.ExtensionRanges().Has(fd.Number()) {
-                       panic("invalid extension field")
+                       panic(fmt.Sprintf("extension %v extends %v outside the extension range", fd.FullName(), mi.Desc.FullName()))
                }
                xtd, ok := fd.(pref.ExtensionTypeDescriptor)
                if !ok {
-                       panic("extension descriptor does not implement ExtensionTypeDescriptor")
+                       panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", fd.FullName()))
                }
                return nil, xtd.Type()
        }
-       panic("invalid field descriptor")
+       panic(fmt.Sprintf("field %v is invalid", fd.FullName()))
 }
index 7b87d4712f27009e726e4a3dbe168dd295784402..23124a86e40cc23b39f663d1184c663a0c83cb3e 100644 (file)
@@ -31,13 +31,13 @@ type fieldInfo struct {
 func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x exporter, ot reflect.Type) fieldInfo {
        ft := fs.Type
        if ft.Kind() != reflect.Interface {
-               panic(fmt.Sprintf("invalid type: got %v, want interface kind", ft))
+               panic(fmt.Sprintf("field %v has invalid type: got %v, want interface kind", fd.FullName(), ft))
        }
        if ot.Kind() != reflect.Struct {
-               panic(fmt.Sprintf("invalid type: got %v, want struct kind", ot))
+               panic(fmt.Sprintf("field %v has invalid type: got %v, want struct kind", fd.FullName(), ot))
        }
        if !reflect.PtrTo(ot).Implements(ft) {
-               panic(fmt.Sprintf("invalid type: %v does not implement %v", ot, ft))
+               panic(fmt.Sprintf("field %v has invalid type: %v does not implement %v", fd.FullName(), ot, ft))
        }
        conv := NewConverter(ot.Field(0).Type, fd)
        isMessage := fd.Message() != nil
@@ -90,7 +90,7 @@ func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x export
                },
                mutable: func(p pointer) pref.Value {
                        if !isMessage {
-                               panic("invalid Mutable on field with non-composite type")
+                               panic(fmt.Sprintf("field %v with invalid Mutable call on field with non-composite type", fd.FullName()))
                        }
                        rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
                        if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
@@ -114,7 +114,7 @@ func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x export
 func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
        ft := fs.Type
        if ft.Kind() != reflect.Map {
-               panic(fmt.Sprintf("invalid type: got %v, want map kind", ft))
+               panic(fmt.Sprintf("field %v has invalid type: got %v, want map kind", fd.FullName(), ft))
        }
        conv := NewConverter(ft, fd)
 
@@ -147,7 +147,7 @@ func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter
                        rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
                        pv := conv.GoValueOf(v)
                        if pv.IsNil() {
-                               panic(fmt.Sprintf("invalid value: setting map field to read-only value"))
+                               panic(fmt.Sprintf("map field %v cannot be set with read-only value", fd.FullName()))
                        }
                        rv.Set(pv)
                },
@@ -167,7 +167,7 @@ func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter
 func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
        ft := fs.Type
        if ft.Kind() != reflect.Slice {
-               panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft))
+               panic(fmt.Sprintf("field %v has invalid type: got %v, want slice kind", fd.FullName(), ft))
        }
        conv := NewConverter(reflect.PtrTo(ft), fd)
 
@@ -200,7 +200,7 @@ func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporte
                        rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
                        pv := conv.GoValueOf(v)
                        if pv.IsNil() {
-                               panic(fmt.Sprintf("invalid value: setting repeated field to read-only value"))
+                               panic(fmt.Sprintf("list field %v cannot be set with read-only value", fd.FullName()))
                        }
                        rv.Set(pv.Elem())
                },
@@ -221,11 +221,11 @@ var (
 
 func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
        ft := fs.Type
-       nullable := fd.Syntax() == pref.Proto2
+       nullable := fd.HasPresence()
        isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8
        if nullable {
                if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice {
-                       panic(fmt.Sprintf("invalid type: got %v, want pointer", ft))
+                       panic(fmt.Sprintf("field %v has invalid type: got %v, want pointer", fd.FullName(), ft))
                }
                if ft.Kind() == reflect.Ptr {
                        ft = ft.Elem()
@@ -257,7 +257,7 @@ func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x expor
                        case reflect.String, reflect.Slice:
                                return rv.Len() > 0
                        default:
-                               panic(fmt.Sprintf("invalid type: %v", rv.Type())) // should never happen
+                               panic(fmt.Sprintf("field %v has invalid type: %v", fd.FullName(), rv.Type())) // should never happen
                        }
                },
                clear: func(p pointer) {
@@ -290,9 +290,9 @@ func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x expor
                        rv.Set(conv.GoValueOf(v))
                        if isBytes && rv.Len() == 0 {
                                if nullable {
-                                       rv.Set(emptyBytes) // preserve presence in proto2
+                                       rv.Set(emptyBytes) // preserve presence
                                } else {
-                                       rv.Set(nilBytes) // do not preserve presence in proto3
+                                       rv.Set(nilBytes) // do not preserve presence
                                }
                        }
                },
@@ -314,7 +314,7 @@ func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldIn
                        messageName := fd.Message().FullName()
                        messageType, _ = preg.GlobalTypes.FindMessageByName(messageName)
                        if messageType == nil {
-                               panic(fmt.Sprintf("weak message %v is not linked in", messageName))
+                               panic(fmt.Sprintf("weak message %v for field %v is not linked in", messageName, fd.FullName()))
                        }
                })
        }
@@ -347,7 +347,10 @@ func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldIn
                        lazyInit()
                        m := v.Message()
                        if m.Descriptor() != messageType.Descriptor() {
-                               panic("mismatching message descriptor")
+                               if got, want := m.Descriptor().FullName(), messageType.Descriptor().FullName(); got != want {
+                                       panic(fmt.Sprintf("field %v has mismatching message descriptor: got %v, want %v", fd.FullName(), got, want))
+                               }
+                               panic(fmt.Sprintf("field %v has mismatching message descriptor: %v", fd.FullName(), m.Descriptor().FullName()))
                        }
                        p.Apply(weakOffset).WeakFields().set(num, m.Interface())
                },
@@ -402,7 +405,7 @@ func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField, x expo
                        rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
                        rv.Set(conv.GoValueOf(v))
                        if rv.IsNil() {
-                               panic("invalid nil pointer")
+                               panic(fmt.Sprintf("field %v has invalid nil pointer", fd.FullName()))
                        }
                },
                mutable: func(p pointer) pref.Value {
@@ -426,11 +429,25 @@ type oneofInfo struct {
        which     func(pointer) pref.FieldNumber
 }
 
-func makeOneofInfo(od pref.OneofDescriptor, fs reflect.StructField, x exporter, wrappersByType map[reflect.Type]pref.FieldNumber) *oneofInfo {
-       fieldOffset := offsetOf(fs, x)
-       return &oneofInfo{
-               oneofDesc: od,
-               which: func(p pointer) pref.FieldNumber {
+func makeOneofInfo(od pref.OneofDescriptor, si structInfo, x exporter) *oneofInfo {
+       oi := &oneofInfo{oneofDesc: od}
+       if od.IsSynthetic() {
+               fs := si.fieldsByNumber[od.Fields().Get(0).Number()]
+               fieldOffset := offsetOf(fs, x)
+               oi.which = func(p pointer) pref.FieldNumber {
+                       if p.IsNil() {
+                               return 0
+                       }
+                       rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
+                       if rv.IsNil() { // valid on either *T or []byte
+                               return 0
+                       }
+                       return od.Fields().Get(0).Number()
+               }
+       } else {
+               fs := si.oneofsByName[od.Name()]
+               fieldOffset := offsetOf(fs, x)
+               oi.which = func(p pointer) pref.FieldNumber {
                        if p.IsNil() {
                                return 0
                        }
@@ -442,7 +459,8 @@ func makeOneofInfo(od pref.OneofDescriptor, fs reflect.StructField, x exporter,
                        if rv.IsNil() {
                                return 0
                        }
-                       return wrappersByType[rv.Type().Elem()]
-               },
+                       return si.oneofWrappersByType[rv.Type().Elem()]
+               }
        }
+       return oi
 }
index 7d65f5ca28723631e8058ed0c355e5990d5e516f..741d6e5b6bd21389859a95b73e856910a59be0cc 100644 (file)
@@ -114,7 +114,7 @@ func (m *messageState) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.
        if oi := m.messageInfo().oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
                return od.Fields().ByNumber(oi.which(m.pointer()))
        }
-       panic("invalid oneof descriptor")
+       panic("invalid oneof descriptor " + string(od.FullName()) + " for message " + string(m.Descriptor().FullName()))
 }
 func (m *messageState) GetUnknown() protoreflect.RawFields {
        m.messageInfo().init()
@@ -234,7 +234,7 @@ func (m *messageReflectWrapper) WhichOneof(od protoreflect.OneofDescriptor) prot
        if oi := m.messageInfo().oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
                return od.Fields().ByNumber(oi.which(m.pointer()))
        }
-       panic("invalid oneof descriptor")
+       panic("invalid oneof descriptor " + string(od.FullName()) + " for message " + string(m.Descriptor().FullName()))
 }
 func (m *messageReflectWrapper) GetUnknown() protoreflect.RawFields {
        m.messageInfo().init()
index 274164336fa332681b92a999f2dffcbfb82113b0..088aa85d483d7b9b29c9c963efe37ce338fc330f 100644 (file)
@@ -148,7 +148,11 @@ func (ms *messageState) pointer() pointer {
        return pointer{p: unsafe.Pointer(ms)}
 }
 func (ms *messageState) messageInfo() *MessageInfo {
-       return ms.LoadMessageInfo()
+       mi := ms.LoadMessageInfo()
+       if mi == nil {
+               panic("invalid nil message info; this suggests memory corruption due to a race or shallow copy on the message struct")
+       }
+       return mi
 }
 func (ms *messageState) LoadMessageInfo() *MessageInfo {
        return (*MessageInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&ms.atomicMessageInfo))))
index 39d62fd06894d7e7c3382c17a534acf139896f10..57de9cc85b13586f433647ac9f760655d9fb220f 100644 (file)
@@ -108,7 +108,7 @@ const (
 func newFieldValidationInfo(mi *MessageInfo, si structInfo, fd pref.FieldDescriptor, ft reflect.Type) validationInfo {
        var vi validationInfo
        switch {
-       case fd.ContainingOneof() != nil:
+       case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic():
                switch fd.Kind() {
                case pref.MessageKind:
                        vi.typ = validationTypeMessage
index 575c988ccb2fe79df8989facaec106d16b0fbe02..009cbefd1ed2ced72387cd6ffea24697e14535af 100644 (file)
@@ -5,9 +5,10 @@
 package impl
 
 import (
-       "reflect"
+       "fmt"
 
        pref "google.golang.org/protobuf/reflect/protoreflect"
+       "google.golang.org/protobuf/reflect/protoregistry"
 )
 
 // weakFields adds methods to the exported WeakFields type for internal use.
@@ -16,31 +17,58 @@ import (
 // defined directly on it.
 type weakFields WeakFields
 
-func (w *weakFields) get(num pref.FieldNumber) (_ pref.ProtoMessage, ok bool) {
-       if *w == nil {
-               return nil, false
-       }
-       m, ok := (*w)[int32(num)]
-       if !ok {
-               return nil, false
-       }
-       // As a legacy quirk, consider a typed nil to be unset.
-       //
-       // TODO: Consider fixing the generated set methods to clear the field
-       // when provided with a typed nil.
-       if v := reflect.ValueOf(m); v.Kind() == reflect.Ptr && v.IsNil() {
-               return nil, false
-       }
-       return Export{}.ProtoMessageV2Of(m), true
+func (w weakFields) get(num pref.FieldNumber) (pref.ProtoMessage, bool) {
+       m, ok := w[int32(num)]
+       return m, ok
 }
 
 func (w *weakFields) set(num pref.FieldNumber, m pref.ProtoMessage) {
        if *w == nil {
                *w = make(weakFields)
        }
-       (*w)[int32(num)] = Export{}.ProtoMessageV1Of(m)
+       (*w)[int32(num)] = m
 }
 
 func (w *weakFields) clear(num pref.FieldNumber) {
        delete(*w, int32(num))
 }
+
+func (Export) HasWeak(w WeakFields, num pref.FieldNumber) bool {
+       _, ok := w[int32(num)]
+       return ok
+}
+
+func (Export) ClearWeak(w *WeakFields, num pref.FieldNumber) {
+       delete(*w, int32(num))
+}
+
+func (Export) GetWeak(w WeakFields, num pref.FieldNumber, name pref.FullName) pref.ProtoMessage {
+       if m, ok := w[int32(num)]; ok {
+               return m
+       }
+       mt, _ := protoregistry.GlobalTypes.FindMessageByName(name)
+       if mt == nil {
+               panic(fmt.Sprintf("message %v for weak field is not linked in", name))
+       }
+       return mt.Zero().Interface()
+}
+
+func (Export) SetWeak(w *WeakFields, num pref.FieldNumber, name pref.FullName, m pref.ProtoMessage) {
+       if m != nil {
+               mt, _ := protoregistry.GlobalTypes.FindMessageByName(name)
+               if mt == nil {
+                       panic(fmt.Sprintf("message %v for weak field is not linked in", name))
+               }
+               if mt != m.ProtoReflect().Type() {
+                       panic(fmt.Sprintf("invalid message type for weak field: got %T, want %T", m, mt.Zero().Interface()))
+               }
+       }
+       if m == nil || !m.ProtoReflect().IsValid() {
+               delete(*w, int32(num))
+               return
+       }
+       if *w == nil {
+               *w = make(weakFields)
+       }
+       (*w)[int32(num)] = m
+}
index cd84284c9d1dbf5656645381baae32e07ab8a85e..4088e59c6f5102ce7e1ba486c90350fecb27e00d 100644 (file)
@@ -52,7 +52,7 @@ import (
 //     10. Send out the CL for review and submit it.
 const (
        Major      = 1
-       Minor      = 21
+       Minor      = 23
        Patch      = 0
        PreRelease = ""
 )
index d7c99235ecfe71f8dbc58a4deb1f0dc997bc1fed..3e9a6a2f66c77cdcb18acb3bb56ffa36be9e5a18 100644 (file)
@@ -12,6 +12,12 @@ import (
 
 // CheckInitialized returns an error if any required fields in m are not set.
 func CheckInitialized(m Message) error {
+       // Treat a nil message interface as an "untyped" empty message,
+       // which we assume to have no required fields.
+       if m == nil {
+               return nil
+       }
+
        return checkInitialized(m.ProtoReflect())
 }
 
index fa738a15da9b950d31b0bd94cbf23471eb0e7448..456bfda47892addd67c924fb045c411823508321 100644 (file)
@@ -74,19 +74,54 @@ type MarshalOptions struct {
 
 // Marshal returns the wire-format encoding of m.
 func Marshal(m Message) ([]byte, error) {
+       // Treat nil message interface as an empty message; nothing to output.
+       if m == nil {
+               return nil, nil
+       }
+
        out, err := MarshalOptions{}.marshal(nil, m.ProtoReflect())
+       if len(out.Buf) == 0 && err == nil {
+               out.Buf = emptyBytesForMessage(m)
+       }
        return out.Buf, err
 }
 
 // Marshal returns the wire-format encoding of m.
 func (o MarshalOptions) Marshal(m Message) ([]byte, error) {
+       // Treat nil message interface as an empty message; nothing to output.
+       if m == nil {
+               return nil, nil
+       }
+
        out, err := o.marshal(nil, m.ProtoReflect())
+       if len(out.Buf) == 0 && err == nil {
+               out.Buf = emptyBytesForMessage(m)
+       }
        return out.Buf, err
 }
 
+// emptyBytesForMessage returns a nil buffer if and only if m is invalid,
+// otherwise it returns a non-nil empty buffer.
+//
+// This is to assist the edge-case where user-code does the following:
+//     m1.OptionalBytes, _ = proto.Marshal(m2)
+// where they expect the proto2 "optional_bytes" field to be populated
+// if any only if m2 is a valid message.
+func emptyBytesForMessage(m Message) []byte {
+       if m == nil || !m.ProtoReflect().IsValid() {
+               return nil
+       }
+       return emptyBuf[:]
+}
+
 // MarshalAppend appends the wire-format encoding of m to b,
 // returning the result.
 func (o MarshalOptions) MarshalAppend(b []byte, m Message) ([]byte, error) {
+       // Treat nil message interface as an empty message; nothing to append.
+       if m == nil {
+               return b, nil
+       }
+
        out, err := o.marshal(b, m.ProtoReflect())
        return out.Buf, err
 }
index 73f2431f1a23e9ba2c2cdaec581caae8e189a673..5f293cda86996b5e903d68c7bb838cc3427790bb 100644 (file)
@@ -9,28 +9,84 @@ import (
 )
 
 // HasExtension reports whether an extension field is populated.
-// It panics if ext does not extend m.
-func HasExtension(m Message, ext protoreflect.ExtensionType) bool {
-       return m.ProtoReflect().Has(ext.TypeDescriptor())
+// It returns false if m is invalid or if xt does not extend m.
+func HasExtension(m Message, xt protoreflect.ExtensionType) bool {
+       // Treat nil message interface as an empty message; no populated fields.
+       if m == nil {
+               return false
+       }
+
+       // As a special-case, we reports invalid or mismatching descriptors
+       // as always not being populated (since they aren't).
+       if xt == nil || m.ProtoReflect().Descriptor() != xt.TypeDescriptor().ContainingMessage() {
+               return false
+       }
+
+       return m.ProtoReflect().Has(xt.TypeDescriptor())
 }
 
 // ClearExtension clears an extension field such that subsequent
 // HasExtension calls return false.
-// It panics if ext does not extend m.
-func ClearExtension(m Message, ext protoreflect.ExtensionType) {
-       m.ProtoReflect().Clear(ext.TypeDescriptor())
+// It panics if m is invalid or if xt does not extend m.
+func ClearExtension(m Message, xt protoreflect.ExtensionType) {
+       m.ProtoReflect().Clear(xt.TypeDescriptor())
 }
 
 // GetExtension retrieves the value for an extension field.
 // If the field is unpopulated, it returns the default value for
-// scalars and an immutable, empty value for lists, maps, or messages.
-// It panics if ext does not extend m.
-func GetExtension(m Message, ext protoreflect.ExtensionType) interface{} {
-       return ext.InterfaceOf(m.ProtoReflect().Get(ext.TypeDescriptor()))
+// scalars and an immutable, empty value for lists or messages.
+// It panics if xt does not extend m.
+func GetExtension(m Message, xt protoreflect.ExtensionType) interface{} {
+       // Treat nil message interface as an empty message; return the default.
+       if m == nil {
+               return xt.InterfaceOf(xt.Zero())
+       }
+
+       return xt.InterfaceOf(m.ProtoReflect().Get(xt.TypeDescriptor()))
 }
 
 // SetExtension stores the value of an extension field.
-// It panics if ext does not extend m or if value type is invalid for the field.
-func SetExtension(m Message, ext protoreflect.ExtensionType, value interface{}) {
-       m.ProtoReflect().Set(ext.TypeDescriptor(), ext.ValueOf(value))
+// It panics if m is invalid, xt does not extend m, or if type of v
+// is invalid for the specified extension field.
+func SetExtension(m Message, xt protoreflect.ExtensionType, v interface{}) {
+       xd := xt.TypeDescriptor()
+       pv := xt.ValueOf(v)
+
+       // Specially treat an invalid list, map, or message as clear.
+       isValid := true
+       switch {
+       case xd.IsList():
+               isValid = pv.List().IsValid()
+       case xd.IsMap():
+               isValid = pv.Map().IsValid()
+       case xd.Message() != nil:
+               isValid = pv.Message().IsValid()
+       }
+       if !isValid {
+               m.ProtoReflect().Clear(xd)
+               return
+       }
+
+       m.ProtoReflect().Set(xd, pv)
+}
+
+// RangeExtensions iterates over every populated extension field in m in an
+// undefined order, calling f for each extension type and value encountered.
+// It returns immediately if f returns false.
+// While iterating, mutating operations may only be performed
+// on the current extension field.
+func RangeExtensions(m Message, f func(protoreflect.ExtensionType, interface{}) bool) {
+       // Treat nil message interface as an empty message; nothing to range over.
+       if m == nil {
+               return
+       }
+
+       m.ProtoReflect().Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
+               if fd.IsExtension() {
+                       xt := fd.(protoreflect.ExtensionTypeDescriptor).Type()
+                       vi := xt.InterfaceOf(v)
+                       return f(xt, vi)
+               }
+               return true
+       })
 }
index df72f989529442b7dc2d6f1d258a6b3853862d28..d761ab331d1ce86d299e22a6e6a288b73b231979 100644 (file)
@@ -5,6 +5,8 @@
 package proto
 
 import (
+       "fmt"
+
        "google.golang.org/protobuf/reflect/protoreflect"
        "google.golang.org/protobuf/runtime/protoiface"
 )
@@ -21,8 +23,14 @@ import (
 // It is semantically equivalent to unmarshaling the encoded form of src
 // into dst with the UnmarshalOptions.Merge option specified.
 func Merge(dst, src Message) {
+       // TODO: Should nil src be treated as semantically equivalent to a
+       // untyped, read-only, empty message? What about a nil dst?
+
        dstMsg, srcMsg := dst.ProtoReflect(), src.ProtoReflect()
        if dstMsg.Descriptor() != srcMsg.Descriptor() {
+               if got, want := dstMsg.Descriptor().FullName(), srcMsg.Descriptor().FullName(); got != want {
+                       panic(fmt.Sprintf("descriptor mismatch: %v != %v", got, want))
+               }
                panic("descriptor mismatch")
        }
        mergeOptions{}.mergeMessage(dstMsg, srcMsg)
@@ -69,7 +77,7 @@ func (o mergeOptions) mergeMessage(dst, src protoreflect.Message) {
        }
 
        if !dst.IsValid() {
-               panic("cannot merge into invalid destination message")
+               panic(fmt.Sprintf("cannot merge into invalid %v message", dst.Descriptor().FullName()))
        }
 
        src.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
index 22048bc1fab7381dd3e0af861c6f4f3b7ff2d8d8..3d7f894362f5cd65f5b78db8d2ae14c68fcdd844 100644 (file)
@@ -4,7 +4,11 @@
 
 package proto
 
-import "google.golang.org/protobuf/reflect/protoreflect"
+import (
+       "fmt"
+
+       "google.golang.org/protobuf/reflect/protoreflect"
+)
 
 // Reset clears every field in the message.
 // The resulting message shares no observable memory with its previous state
@@ -19,7 +23,7 @@ func Reset(m Message) {
 
 func resetMessage(m protoreflect.Message) {
        if !m.IsValid() {
-               panic("cannot reset invalid message")
+               panic(fmt.Sprintf("cannot reset invalid %v message", m.Descriptor().FullName()))
        }
 
        // Clear all known fields.
index a4e72bd9c0b0c5c18a47d72db411f39612fadd93..11ba8414643e86a996bae763e70421c6842d9bf3 100644 (file)
@@ -18,6 +18,11 @@ func Size(m Message) int {
 
 // Size returns the size in bytes of the wire-format encoding of m.
 func (o MarshalOptions) Size(m Message) int {
+       // Treat a nil message interface as an empty message; nothing to output.
+       if m == nil {
+               return 0
+       }
+
        return sizeMessage(m.ProtoReflect())
 }
 
index 1b89bedabd92cc413ebaeba402f389473225df42..b669a4e7619dfb2384830ef9e0062c3e9b17a50f 100644 (file)
@@ -22,8 +22,9 @@
 //
 // The protobuf descriptor interfaces are not meant to be implemented by
 // user code since they might need to be extended in the future to support
-// additions to the protobuf language. Protobuf descriptors can be constructed
-// using the "google.golang.org/protobuf/reflect/protodesc" package.
+// additions to the protobuf language.
+// The "google.golang.org/protobuf/reflect/protodesc" package converts between
+// google.protobuf.DescriptorProto messages and protobuf descriptors.
 //
 //
 // Go Type Descriptors
index 41d560e738f82e8279fbe230fcb4410f3dabb42b..5be14a7258467cd9eeca9b8dcfc0e78a8ced35e8 100644 (file)
@@ -281,11 +281,19 @@ type FieldDescriptor interface {
        // It is usually the camel-cased form of the field name.
        JSONName() string
 
+       // HasPresence reports whether the field distinguishes between unpopulated
+       // and default values.
+       HasPresence() bool
+
        // IsExtension reports whether this is an extension field. If false,
        // then Parent and ContainingMessage refer to the same message.
        // Otherwise, ContainingMessage and Parent likely differ.
        IsExtension() bool
 
+       // HasOptionalKeyword reports whether the "optional" keyword was explicitly
+       // specified in the source .proto file.
+       HasOptionalKeyword() bool
+
        // IsWeak reports whether this is a weak field, which does not impose a
        // direct dependency on the target type.
        // If true, then Message returns a placeholder type.
@@ -375,6 +383,11 @@ type FieldDescriptors interface {
 type OneofDescriptor interface {
        Descriptor
 
+       // IsSynthetic reports whether this is a synthetic oneof created to support
+       // proto3 optional semantics. If true, Fields contains exactly one field
+       // with HasOptionalKeyword specified.
+       IsSynthetic() bool
+
        // Fields is a list of fields belonging to this oneof.
        Fields() FieldDescriptors
 
index a352ed9e6cd2a52403ddc2d75439b9db6c7c04cf..f31981077827f2ee8408dcc27de2348e68fec5af 100644 (file)
@@ -114,8 +114,8 @@ type Message interface {
        // Mutable is a mutating operation and unsafe for concurrent use.
        Mutable(FieldDescriptor) Value
 
-       // NewField returns a new value for assignable to the field of a given descriptor.
-       // For scalars, this returns the default value.
+       // NewField returns a new value that is assignable to the field
+       // for the given descriptor. For scalars, this returns the default value.
        // For lists, maps, and messages, this returns a new, empty, mutable value.
        NewField(FieldDescriptor) Value
 
index d695a4d66232ea055a995c54c95177f7a0bbabf7..f334f71bcb438afd1b6f3784d3256f64272d9137 100644 (file)
@@ -7,7 +7,6 @@ package protoreflect
 import (
        "fmt"
        "math"
-       "reflect"
 )
 
 // Value is a union where only one Go type may be set at a time.
@@ -87,7 +86,7 @@ func ValueOf(v interface{}) Value {
        case Message, List, Map:
                return valueOfIface(v)
        default:
-               panic(fmt.Sprintf("invalid type: %v", reflect.TypeOf(v)))
+               panic(fmt.Sprintf("invalid type: %T", v))
        }
 }
 
@@ -197,13 +196,55 @@ func (v Value) Interface() interface{} {
        }
 }
 
+func (v Value) typeName() string {
+       switch v.typ {
+       case nilType:
+               return "nil"
+       case boolType:
+               return "bool"
+       case int32Type:
+               return "int32"
+       case int64Type:
+               return "int64"
+       case uint32Type:
+               return "uint32"
+       case uint64Type:
+               return "uint64"
+       case float32Type:
+               return "float32"
+       case float64Type:
+               return "float64"
+       case stringType:
+               return "string"
+       case bytesType:
+               return "bytes"
+       case enumType:
+               return "enum"
+       default:
+               switch v := v.getIface().(type) {
+               case Message:
+                       return "message"
+               case List:
+                       return "list"
+               case Map:
+                       return "map"
+               default:
+                       return fmt.Sprintf("<unknown: %T>", v)
+               }
+       }
+}
+
+func (v Value) panicMessage(what string) string {
+       return fmt.Sprintf("type mismatch: cannot convert %v to %s", v.typeName(), what)
+}
+
 // Bool returns v as a bool and panics if the type is not a bool.
 func (v Value) Bool() bool {
        switch v.typ {
        case boolType:
                return v.num > 0
        default:
-               panic("proto: value type mismatch")
+               panic(v.panicMessage("bool"))
        }
 }
 
@@ -213,7 +254,7 @@ func (v Value) Int() int64 {
        case int32Type, int64Type:
                return int64(v.num)
        default:
-               panic("proto: value type mismatch")
+               panic(v.panicMessage("int"))
        }
 }
 
@@ -223,7 +264,7 @@ func (v Value) Uint() uint64 {
        case uint32Type, uint64Type:
                return uint64(v.num)
        default:
-               panic("proto: value type mismatch")
+               panic(v.panicMessage("uint"))
        }
 }
 
@@ -233,7 +274,7 @@ func (v Value) Float() float64 {
        case float32Type, float64Type:
                return math.Float64frombits(uint64(v.num))
        default:
-               panic("proto: value type mismatch")
+               panic(v.panicMessage("float"))
        }
 }
 
@@ -254,7 +295,7 @@ func (v Value) Bytes() []byte {
        case bytesType:
                return v.getBytes()
        default:
-               panic("proto: value type mismatch")
+               panic(v.panicMessage("bytes"))
        }
 }
 
@@ -264,37 +305,37 @@ func (v Value) Enum() EnumNumber {
        case enumType:
                return EnumNumber(v.num)
        default:
-               panic("proto: value type mismatch")
+               panic(v.panicMessage("enum"))
        }
 }
 
 // Message returns v as a Message and panics if the type is not a Message.
 func (v Value) Message() Message {
-       switch v := v.getIface().(type) {
+       switch vi := v.getIface().(type) {
        case Message:
-               return v
+               return vi
        default:
-               panic("proto: value type mismatch")
+               panic(v.panicMessage("message"))
        }
 }
 
 // List returns v as a List and panics if the type is not a List.
 func (v Value) List() List {
-       switch v := v.getIface().(type) {
+       switch vi := v.getIface().(type) {
        case List:
-               return v
+               return vi
        default:
-               panic("proto: value type mismatch")
+               panic(v.panicMessage("list"))
        }
 }
 
 // Map returns v as a Map and panics if the type is not a Map.
 func (v Value) Map() Map {
-       switch v := v.getIface().(type) {
+       switch vi := v.getIface().(type) {
        case Map:
-               return v
+               return vi
        default:
-               panic("proto: value type mismatch")
+               panic(v.panicMessage("map"))
        }
 }
 
@@ -303,8 +344,9 @@ func (v Value) MapKey() MapKey {
        switch v.typ {
        case boolType, int32Type, int64Type, uint32Type, uint64Type, stringType:
                return MapKey(v)
+       default:
+               panic(v.panicMessage("map key"))
        }
-       panic("proto: invalid map key type")
 }
 
 // MapKey is used to index maps, where the Go type of the MapKey must match
index 9f556934d8b91e4412de52c2331263192732d821..7348c50c0c3d7b7884422e0c736b08180ea1961e 100644 (file)
@@ -1,12 +1,17 @@
 language: go
 
 go:
-    - 1.4
-    - 1.5
-    - 1.6
-    - 1.7
-    - 1.8
-    - 1.9
-    - tip
+    - "1.4.x"
+    - "1.5.x"
+    - "1.6.x"
+    - "1.7.x"
+    - "1.8.x"
+    - "1.9.x"
+    - "1.10.x"
+    - "1.11.x"
+    - "1.12.x"
+    - "1.13.x"
+    - "1.14.x"
+    - "tip"
 
 go_import_path: gopkg.in/yaml.v2
index 1f7e87e67275af6c2767393d53b9aab2c0b51962..acf71402cf31a2802efbaf22df09c8d11e8ab560 100644 (file)
@@ -79,6 +79,8 @@ func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
        parser.encoding = encoding
 }
 
+var disableLineWrapping = false
+
 // Create a new emitter object.
 func yaml_emitter_initialize(emitter *yaml_emitter_t) {
        *emitter = yaml_emitter_t{
@@ -87,6 +89,9 @@ func yaml_emitter_initialize(emitter *yaml_emitter_t) {
                states:     make([]yaml_emitter_state_t, 0, initial_stack_size),
                events:     make([]yaml_event_t, 0, initial_queue_size),
        }
+       if disableLineWrapping {
+               emitter.best_width = -1
+       }
 }
 
 // Destroy an emitter object.
index 1934e876945021c3ac47d0aab161477e43ae35a4..2cbb85aeacd79820a623f120d9702834a899ebee 100644 (file)
@@ -1,5 +1,5 @@
-module "gopkg.in/yaml.v2"
+module gopkg.in/yaml.v2
 
-require (
-       "gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405
-)
+go 1.15
+
+require gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
index 570b8ecd10fd5b827f79ad1a14b62ddf8a13f821..0b9bb6030a0fae4384db726f9b51c9ebbd7d5271 100644 (file)
@@ -626,31 +626,18 @@ func trace(args ...interface{}) func() {
 func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {
        // While we need more tokens to fetch, do it.
        for {
-               // Check if we really need to fetch more tokens.
-               need_more_tokens := false
-
-               if parser.tokens_head == len(parser.tokens) {
-                       // Queue is empty.
-                       need_more_tokens = true
-               } else {
-                       // Check if any potential simple key may occupy the head position.
-                       if !yaml_parser_stale_simple_keys(parser) {
+               if parser.tokens_head != len(parser.tokens) {
+                       // If queue is non-empty, check if any potential simple key may
+                       // occupy the head position.
+                       head_tok_idx, ok := parser.simple_keys_by_tok[parser.tokens_parsed]
+                       if !ok {
+                               break
+                       } else if valid, ok := yaml_simple_key_is_valid(parser, &parser.simple_keys[head_tok_idx]); !ok {
                                return false
-                       }
-
-                       for i := range parser.simple_keys {
-                               simple_key := &parser.simple_keys[i]
-                               if simple_key.possible && simple_key.token_number == parser.tokens_parsed {
-                                       need_more_tokens = true
-                                       break
-                               }
+                       } else if !valid {
+                               break
                        }
                }
-
-               // We are finished.
-               if !need_more_tokens {
-                       break
-               }
                // Fetch the next token.
                if !yaml_parser_fetch_next_token(parser) {
                        return false
@@ -678,11 +665,6 @@ func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool {
                return false
        }
 
-       // Remove obsolete potential simple keys.
-       if !yaml_parser_stale_simple_keys(parser) {
-               return false
-       }
-
        // Check the indentation level against the current column.
        if !yaml_parser_unroll_indent(parser, parser.mark.column) {
                return false
@@ -837,29 +819,30 @@ func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool {
                "found character that cannot start any token")
 }
 
-// Check the list of potential simple keys and remove the positions that
-// cannot contain simple keys anymore.
-func yaml_parser_stale_simple_keys(parser *yaml_parser_t) bool {
-       // Check for a potential simple key for each flow level.
-       for i := range parser.simple_keys {
-               simple_key := &parser.simple_keys[i]
-
-               // The specification requires that a simple key
-               //
-               //  - is limited to a single line,
-               //  - is shorter than 1024 characters.
-               if simple_key.possible && (simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index) {
-
-                       // Check if the potential simple key to be removed is required.
-                       if simple_key.required {
-                               return yaml_parser_set_scanner_error(parser,
-                                       "while scanning a simple key", simple_key.mark,
-                                       "could not find expected ':'")
-                       }
-                       simple_key.possible = false
+func yaml_simple_key_is_valid(parser *yaml_parser_t, simple_key *yaml_simple_key_t) (valid, ok bool) {
+       if !simple_key.possible {
+               return false, true
+       }
+
+       // The 1.2 specification says:
+       //
+       //     "If the ? indicator is omitted, parsing needs to see past the
+       //     implicit key to recognize it as such. To limit the amount of
+       //     lookahead required, the “:” indicator must appear at most 1024
+       //     Unicode characters beyond the start of the key. In addition, the key
+       //     is restricted to a single line."
+       //
+       if simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index {
+               // Check if the potential simple key to be removed is required.
+               if simple_key.required {
+                       return false, yaml_parser_set_scanner_error(parser,
+                               "while scanning a simple key", simple_key.mark,
+                               "could not find expected ':'")
                }
+               simple_key.possible = false
+               return false, true
        }
-       return true
+       return true, true
 }
 
 // Check if a simple key may start at the current position and add it if
@@ -879,13 +862,14 @@ func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
                        possible:     true,
                        required:     required,
                        token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
+                       mark:         parser.mark,
                }
-               simple_key.mark = parser.mark
 
                if !yaml_parser_remove_simple_key(parser) {
                        return false
                }
                parser.simple_keys[len(parser.simple_keys)-1] = simple_key
+               parser.simple_keys_by_tok[simple_key.token_number] = len(parser.simple_keys) - 1
        }
        return true
 }
@@ -900,9 +884,10 @@ func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool {
                                "while scanning a simple key", parser.simple_keys[i].mark,
                                "could not find expected ':'")
                }
+               // Remove the key from the stack.
+               parser.simple_keys[i].possible = false
+               delete(parser.simple_keys_by_tok, parser.simple_keys[i].token_number)
        }
-       // Remove the key from the stack.
-       parser.simple_keys[i].possible = false
        return true
 }
 
@@ -912,7 +897,12 @@ const max_flow_level = 10000
 // Increase the flow level and resize the simple key list if needed.
 func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {
        // Reset the simple key on the next level.
-       parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
+       parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{
+               possible:     false,
+               required:     false,
+               token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
+               mark:         parser.mark,
+       })
 
        // Increase the flow level.
        parser.flow_level++
@@ -928,7 +918,9 @@ func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {
 func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool {
        if parser.flow_level > 0 {
                parser.flow_level--
-               parser.simple_keys = parser.simple_keys[:len(parser.simple_keys)-1]
+               last := len(parser.simple_keys) - 1
+               delete(parser.simple_keys_by_tok, parser.simple_keys[last].token_number)
+               parser.simple_keys = parser.simple_keys[:last]
        }
        return true
 }
@@ -1005,6 +997,8 @@ func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool {
        // Initialize the simple key stack.
        parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
 
+       parser.simple_keys_by_tok = make(map[int]int)
+
        // A simple key is allowed at the beginning of the stream.
        parser.simple_key_allowed = true
 
@@ -1286,7 +1280,11 @@ func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
        simple_key := &parser.simple_keys[len(parser.simple_keys)-1]
 
        // Have we found a simple key?
-       if simple_key.possible {
+       if valid, ok := yaml_simple_key_is_valid(parser, simple_key); !ok {
+               return false
+
+       } else if valid {
+
                // Create the KEY token and insert it into the queue.
                token := yaml_token_t{
                        typ:        yaml_KEY_TOKEN,
@@ -1304,6 +1302,7 @@ func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
 
                // Remove the simple key.
                simple_key.possible = false
+               delete(parser.simple_keys_by_tok, simple_key.token_number)
 
                // A simple key cannot follow another simple key.
                parser.simple_key_allowed = false
index de85aa4cdb71b6adf499209d5441c844d6181ff6..30813884c0679281201db03b2342365bb8a6afda 100644 (file)
@@ -89,7 +89,7 @@ func UnmarshalStrict(in []byte, out interface{}) (err error) {
        return unmarshal(in, out, true)
 }
 
-// A Decorder reads and decodes YAML values from an input stream.
+// A Decoder reads and decodes YAML values from an input stream.
 type Decoder struct {
        strict bool
        parser *parser
@@ -175,7 +175,7 @@ func unmarshal(in []byte, out interface{}, strict bool) (err error) {
 //                  Zero valued structs will be omitted if all their public
 //                  fields are zero, unless they implement an IsZero
 //                  method (see the IsZeroer interface type), in which
-//                  case the field will be included if that method returns true.
+//                  case the field will be excluded if IsZero returns true.
 //
 //     flow         Marshal using a flow style (useful for structs,
 //                  sequences and maps).
@@ -464,3 +464,15 @@ func isZero(v reflect.Value) bool {
        }
        return false
 }
+
+// FutureLineWrap globally disables line wrapping when encoding long strings.
+// This is a temporary and thus deprecated method introduced to faciliate
+// migration towards v3, which offers more control of line lengths on
+// individual encodings, and has a default matching the behavior introduced
+// by this function.
+//
+// The default formatting of v2 was erroneously changed in v2.3.0 and reverted
+// in v2.4.0, at which point this function was introduced to help migration.
+func FutureLineWrap() {
+       disableLineWrapping = true
+}
index e25cee563be827c201da827c9c3aacc4bfef7830..f6a9c8e34b1ef95cf8191f7bfbdf85ebad114f42 100644 (file)
@@ -579,6 +579,7 @@ type yaml_parser_t struct {
 
        simple_key_allowed bool                // May a simple key occur at the current position?
        simple_keys        []yaml_simple_key_t // The stack of simple keys.
+       simple_keys_by_tok map[int]int         // possible simple_key indexes indexed by token_number
 
        // Parser stuff
 
index 276c8c72e2427dc895368219563d88bef35c3ab9..15dc4b140881b048d8180abf34d92ccaf168c5e8 100644 (file)
@@ -1,7 +1,7 @@
 # github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
 github.com/alecthomas/template
 github.com/alecthomas/template/parse
-# github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4
+# github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d
 github.com/alecthomas/units
 # github.com/beorn7/perks v1.0.1
 github.com/beorn7/perks/quantile
@@ -12,27 +12,29 @@ github.com/go-kit/kit/log
 github.com/go-kit/kit/log/level
 # github.com/go-logfmt/logfmt v0.5.0
 github.com/go-logfmt/logfmt
-# github.com/golang/protobuf v1.4.0
+# github.com/golang/protobuf v1.4.2
 github.com/golang/protobuf/proto
 github.com/golang/protobuf/ptypes
 github.com/golang/protobuf/ptypes/any
 github.com/golang/protobuf/ptypes/duration
 github.com/golang/protobuf/ptypes/timestamp
+# github.com/jpillora/backoff v1.0.0
+github.com/jpillora/backoff
 # github.com/matttproud/golang_protobuf_extensions v1.0.1
 github.com/matttproud/golang_protobuf_extensions/pbutil
 # github.com/miekg/dns v1.1.29
 github.com/miekg/dns
-# github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223
+# github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f
 github.com/mwitkow/go-conntrack
 # github.com/pkg/errors v0.9.1
 github.com/pkg/errors
-# github.com/prometheus/client_golang v1.6.0
+# github.com/prometheus/client_golang v1.7.1
 github.com/prometheus/client_golang/prometheus
 github.com/prometheus/client_golang/prometheus/internal
 github.com/prometheus/client_golang/prometheus/promhttp
 # github.com/prometheus/client_model v0.2.0
 github.com/prometheus/client_model/go
-# github.com/prometheus/common v0.10.0
+# github.com/prometheus/common v0.15.0
 github.com/prometheus/common/config
 github.com/prometheus/common/expfmt
 github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg
@@ -40,14 +42,19 @@ github.com/prometheus/common/model
 github.com/prometheus/common/promlog
 github.com/prometheus/common/promlog/flag
 github.com/prometheus/common/version
-# github.com/prometheus/procfs v0.0.11
+# github.com/prometheus/exporter-toolkit v0.4.0
+github.com/prometheus/exporter-toolkit/https
+github.com/prometheus/exporter-toolkit/https/kingpinflag
+# github.com/prometheus/procfs v0.1.3
 github.com/prometheus/procfs
 github.com/prometheus/procfs/internal/fs
 github.com/prometheus/procfs/internal/util
-# golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
+# golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9
+golang.org/x/crypto/bcrypt
+golang.org/x/crypto/blowfish
 golang.org/x/crypto/ed25519
 golang.org/x/crypto/ed25519/internal/edwards25519
-# golang.org/x/net v0.0.0-20200602114024-627f9648deb9
+# golang.org/x/net v0.0.0-20200625001655-4c5254603344
 golang.org/x/net/bpf
 golang.org/x/net/http/httpguts
 golang.org/x/net/http2
@@ -61,7 +68,8 @@ golang.org/x/net/ipv4
 golang.org/x/net/ipv6
 golang.org/x/net/publicsuffix
 golang.org/x/net/trace
-# golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f
+# golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae
+golang.org/x/sys/internal/unsafeheader
 golang.org/x/sys/unix
 golang.org/x/sys/windows
 # golang.org/x/text v0.3.2
@@ -69,7 +77,7 @@ golang.org/x/text/secure/bidirule
 golang.org/x/text/transform
 golang.org/x/text/unicode/bidi
 golang.org/x/text/unicode/norm
-# google.golang.org/protobuf v1.21.0
+# google.golang.org/protobuf v1.23.0
 google.golang.org/protobuf/encoding/prototext
 google.golang.org/protobuf/encoding/protowire
 google.golang.org/protobuf/internal/descfmt
@@ -102,7 +110,7 @@ google.golang.org/protobuf/types/known/durationpb
 google.golang.org/protobuf/types/known/timestamppb
 # gopkg.in/alecthomas/kingpin.v2 v2.2.6
 gopkg.in/alecthomas/kingpin.v2
-# gopkg.in/yaml.v2 v2.2.5
+# gopkg.in/yaml.v2 v2.4.0
 gopkg.in/yaml.v2
 # gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
 gopkg.in/yaml.v3