Compare commits

...

97 Commits

Author SHA1 Message Date
Aliaksandr Valialkin
15613e5338 app/vmselect/promql: swap binary operation with modifier in the error message for improved readability 2019-06-12 17:14:39 +03:00
Aliaksandr Valialkin
3237d0309c app/vmselect/promql: list a sample of duplicate time series in the error message for group_left or group_right
This should improve troubleshooting for complex queries involving `group_left` and `group_right` modifiers.
2019-06-12 16:57:37 +03:00
Aliaksandr Valialkin
26f8d7ea1b lib/fs: sync parent dir in MustRemoveAll only if it exists
The parent directory may be non-existing when the deleted directory
didn't exist before the MustRemoveAll call
2019-06-12 02:14:44 +03:00
Aliaksandr Valialkin
419197ba08 lib/fs: consolidate *RemoveAll* funcs into a single MustRemoveAll func
The func syncs parent dir in order to persist directory removal
in the event of power loss
2019-06-12 01:53:46 +03:00
Aliaksandr Valialkin
a4b4db9bf6 README.md: add a chapter about downsampling 2019-06-12 01:32:26 +03:00
Aliaksandr Valialkin
c1276edab5 lib/fs: panic with fatal error when directories cannot be removed
Unremoved directories may lead to inconsistent data directory,
so VictoriaMetrics will fail to start next time.

So panic on the first error when trying to remove directory in order
to simplify recover process.
2019-06-12 01:20:54 +03:00
Aliaksandr Valialkin
2322c9a45a lib/fs: attempt #2 to work around NFS issue with directory removal
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/61
2019-06-12 01:07:05 +03:00
Aliaksandr Valialkin
89b928ff24 vendor: update github.com/VictoriaMetrics/fastcache to v1.5.1 2019-06-11 23:56:08 +03:00
Aliaksandr Valialkin
935bfd7a18 lib/fs: consistency renaming SyncPath -> MustSyncPath, since it doesnt return error 2019-06-11 23:13:49 +03:00
Aliaksandr Valialkin
3dd36b8088 lib/fs: make sure the created directory remains visible in the fs in the event of power loss
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/63
2019-06-11 23:08:09 +03:00
Aliaksandr Valialkin
afb964670a lib/fs: use filepath.Dir instead of filepath.Split, since the filename is unused 2019-06-11 22:54:26 +03:00
Aliaksandr Valialkin
20fc0e0e54 lib/{storage,mergeset}: sync filenames inside part when finalizing the part
Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/63
2019-06-11 21:51:13 +03:00
Aliaksandr Valialkin
4d9f088526 README.md: add examples on how to write data with Graphite and OpenTSDB protocols 2019-06-11 21:24:32 +03:00
Aliaksandr Valialkin
82d1707861 README.md: add missing port to example urls 2019-06-11 21:05:24 +03:00
Aliaksandr Valialkin
70d20ce8de README.md: use proper urls for single-node version in examples 2019-06-11 20:33:52 +03:00
Aliaksandr Valialkin
723bf1af7f README.md: add example on how to write data with Influx line protocol to VictoriaMetrics 2019-06-11 20:31:25 +03:00
Aliaksandr Valialkin
ac7b186f13 all: try hard removing directory with contents
Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/61
2019-06-11 01:57:59 +03:00
Roman Khavronenko
cd1bc32158 convert dashboard for provisioning (#62) 2019-06-11 01:07:09 +03:00
Aliaksandr Valialkin
1c33b5937e app/vmselect/promql: prevent from count_values explosion of timeseries, which could result in OOM 2019-06-11 01:03:13 +03:00
Aliaksandr Valialkin
8bb6bc986d app/vmselect/promql: skip superflouos timestamps copying in count_values 2019-06-11 00:44:01 +03:00
Aliaksandr Valialkin
d2be567482 app/vmselect/promql: remove superflouos timeseries copy in histogram_quantile func 2019-06-11 00:39:41 +03:00
Aliaksandr Valialkin
7e7d4d5275 app/vmselect/promql: remove superflouos timeseries copy in union func 2019-06-11 00:35:20 +03:00
Aliaksandr Valialkin
bf9782eaf6 app/vmselect/promql: skip NaN values in count_values func 2019-06-10 22:42:32 +03:00
Aliaksandr Valialkin
cbe692f0e2 app/vmselect: add /api/v1/labels/count handler for quick detection of labels with the maximum number of distinct values 2019-06-10 19:55:38 +03:00
Aliaksandr Valialkin
7b6623558f lib/storage: skip adaptive searching for tag filter matching the minimum number of metrics if the identical previous search didn't found such filter
This should improve speed for searching metrics among high number of time series
with high churn rate like in big Kubernetes clusters with frequent deployments.
2019-06-10 14:07:39 +03:00
Aliaksandr Valialkin
a1351bbaee lib/storage: factor out getTagFilterWithMinMetricIDsCountAdaptive from updateMetricIDsForTagFilters 2019-06-10 13:26:44 +03:00
Aliaksandr Valialkin
b4d707d9bb lib/storage: give clearer names to more functions 2019-06-10 13:01:23 +03:00
Aliaksandr Valialkin
bee7298f81 lib/storage: give more clear names to functions 2019-06-10 12:50:44 +03:00
Aliaksandr Valialkin
dbd217b8f0 lib/storage: test GetSeriesCount 2019-06-10 12:43:34 +03:00
Aliaksandr Valialkin
4d936b1524 lib/storage: make getSeriesCount func indexSearch method 2019-06-10 12:29:11 +03:00
Aliaksandr Valialkin
7354090aad app/vmstorage: add missing _total suffixes to newly added metrics 2019-06-09 22:11:36 +03:00
Aliaksandr Valialkin
d37924900b lib/storage: optimize time series lookup for recent hours when the db contains many millions of time series with high churn rate (aka frequent deployments in Kubernetes) 2019-06-09 19:13:56 +03:00
Aliaksandr Valialkin
c0baa977cf app/vminsert/concurrencylimiter: typo fix in the error message 2019-06-08 22:43:33 +03:00
Aliaksandr Valialkin
f4252f87e6 app/vminsert: really fix #60
ReadLinesBlock may accept dstBuf with non-zero length. In this case the last line without trailing newline isn't read.
Fix this by comparing len(dstBuf) to 0 instead of its original length.
2019-06-07 23:37:03 +03:00
Aliaksandr Valialkin
0b78d228d2 app/vminsert: properly read trailing line without newline in the end
This fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/60
2019-06-07 23:17:59 +03:00
Aliaksandr Valialkin
0371c216a7 deployment/docker: move victoriametrics single-node docker image from valyala/victoria-metrics to victoriametrics/victoria-metrics docker hub path 2019-06-07 11:52:53 +03:00
Aliaksandr Valialkin
c1f18ee48d app/vmselect/promql: properly handle {__name__ op "string"} queries
This has been broken in 7294ef333ad26f4f6578b783e97649e58b1f8945 .
2019-06-07 02:02:04 +03:00
Roman Khavronenko
fbd7044b2b Dashboard update (#57)
* split "pending datapoints" by storage and index pending entities

* update provisioned dVM dashboard
2019-06-07 01:31:45 +03:00
Roman Khavronenko
2afe511d80 Setup Grafana provisioning for docker-compose setup (#50)
* setup Grafana provisioning for docker-compose setup

* review fixes
2019-06-06 23:37:44 +03:00
Seua Polyakov
f4e63cd070 Add SIGINT as stopsignal to docker file (#54)
Add sigint as stopsignal to docker file. You can find more here: https://docs.docker.com/engine/reference/builder/#usage
With this change, the main process inside the container will receive SIGINT, and after a grace period, SIGKILL.
2019-06-06 22:36:21 +03:00
Aliaksandr Valialkin
667115a5c7 app/vmselect/prometheus: report about incorrect time or duration instead of silently using the default value
This should prevent from incorrect usage of the querying API.

Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/52
2019-06-06 22:18:18 +03:00
Aliaksandr Valialkin
1458450dba app/vmselect/promql: return the correct time series from quantile
Previously arbitrary time series could be returned from `quantile`
depending on sort order for the last data point in the selected range.

Fix this by returning the calculated time series.

Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/55
2019-06-06 17:07:31 +03:00
Aliaksandr Valialkin
5a5ba749f2 README.md: add an example on how Influx line protocol is converted into Prometheus data points 2019-06-06 16:08:29 +03:00
Aliaksandr Valialkin
a3e26de45e lib/procutil: typo fix in comment to WaitForSigterm 2019-06-04 17:31:47 +03:00
Aliaksandr Valialkin
53ea90865d app/vmselect/promql: add -search.disableCache flag for disabling response caching
This may be useful for data back-filling, when the response caching
could interfere badly with newly added data points with timestamps
in the past.
2019-06-04 17:30:45 +03:00
Aliaksandr Valialkin
17f0a53068 app/vminsert: explain that /query request emulation is required for TSBS benchmark 2019-06-03 18:40:27 +03:00
Anton Patsev
b03bdb32ff Prettify Table of contents (#47) 2019-06-03 17:31:15 +03:00
Aliaksandr Valialkin
15f59c6df9 deployment/docker: remove trailing whitespace 2019-06-03 14:53:08 +03:00
Artem Navoiev
da45a20491 docker compose for VM 2019-06-03 09:57:33 +02:00
Roman Khavronenko
5859bb9556 Add grafana dashboard for VM (#46) 2019-06-03 00:25:07 +03:00
Aliaksandr Valialkin
28f6c36ab4 lib/storage: tune updating a map with today`s metric ids
- Increase update iterval from 1s to 10s. This should reduce CPU usage
  for large amounts of metric ids with constant churn.
- Reduce pendingTodayMetricIDsLock lock duration during the update.
2019-06-02 21:58:16 +03:00
Aliaksandr Valialkin
4794f894a4 lib/storage: speed up checking metricID existence in the list for the current date 2019-06-02 18:34:08 +03:00
Aliaksandr Valialkin
c7280ba61a vendor: update deps with make vendor-update 2019-06-01 23:39:58 +03:00
Aliaksandr Valialkin
fbd8b03f15 README.md: fixed the link to yum repository source codes 2019-06-01 13:55:44 +03:00
Aliaksandr Valialkin
d17a47e3e0 README.md: add setting up service chapter 2019-05-31 23:34:09 +03:00
Aliaksandr Valialkin
d6862a2d97 README.md: mention that VictoriaMetrics works with time series data from Kubernetes 2019-05-31 22:53:35 +03:00
Aliaksandr Valialkin
f2cf5d8e36 app/vmselect/promql: allow escaping identifiers with \ and \xXX
Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/42
2019-05-31 17:35:17 +03:00
Aliaksandr Valialkin
27f0d098bd app/victoria-metrics: add make victoria-metrics-arm64 rule for building GOARCH=arm64 binary 2019-05-29 23:07:14 +03:00
Aliaksandr Valialkin
a51ff2c6cb README.md: add LICENSE shield 2019-05-29 14:09:36 +03:00
Aliaksandr Valialkin
56b952c456 app/vminsert: add -maxConcurrentInserts command-line flag for limiting the number of concurrent inserts 2019-05-29 12:41:23 +03:00
Aliaksandr Valialkin
61bad1e07e Makefile: run go vet with -mod=vendor in order to disable downloading vendored deps 2019-05-29 01:38:13 +03:00
Artem Navoiev
be97f764f5 [ci-ci] enable CI (#39) 2019-05-29 01:32:49 +03:00
Artem Navoiev
a576d1f5d3 README.md: add links to slack and telegrams (#40) 2019-05-29 01:30:37 +03:00
Aliaksandr Valialkin
968d094524 app/vminsert: reduce memory usage for Influx, Graphite and OpenTSDB protocols
Do not buffer per-connection data and just store it as it arrives
2019-05-28 18:47:23 +03:00
Aliaksandr Valialkin
e307a4d92c lib/timerpool: use timer pool in concurrency limiters
This should reduce the number of memory allocations in highly loaded system
2019-05-28 17:20:10 +03:00
Aliaksandr Valialkin
0eae39daa7 app/vminsert: properly reset InsertCtx.mrs - they must be empty after Reset call 2019-05-28 16:08:01 +03:00
Aliaksandr Valialkin
437e0b2300 README.md: typo fix 2019-05-27 21:37:48 +03:00
Aliaksandr Valialkin
4b3af728ea README.md: add steps for restoring from a snapshot 2019-05-27 20:36:51 +03:00
Aliaksandr Valialkin
4a12c4c982 README.md: add Third-party contributions section 2019-05-27 20:23:39 +03:00
Anton Patsev
2e75efb64e README.md: add unofficial yum repository (#37) 2019-05-27 20:19:54 +03:00
Aliaksandr Valialkin
25900162f6 Makefile: add -mod=vendor to go test, so tests use external deps from vendor folder 2019-05-27 00:35:46 +03:00
Aliaksandr Valialkin
16afcd6aff vendor: update dependencies with make vendor-update 2019-05-26 23:25:12 +03:00
Aliaksandr Valialkin
c2a5eef5e3 Makefile: pass GO111MODULE=on to all the go invocations 2019-05-26 23:23:43 +03:00
Aliaksandr Valialkin
4859ca0cda app/vmselect: update comment according to the updated code 2019-05-26 22:38:58 +03:00
Aliaksandr Valialkin
feb6b203a4 app/vminsert/influx: try converting string values to numeric values, since Influx agents may send numeric values as strings
Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/34
2019-05-26 22:11:19 +03:00
Aliaksandr Valialkin
51ee990902 README.md: typo fix 2019-05-26 17:59:04 +03:00
Aliaksandr Valialkin
5262aae5da app/vmselect/promql: misspeling fix 2019-05-25 21:53:11 +03:00
Aliaksandr Valialkin
54fb8b21f9 all: fix misspellings 2019-05-25 21:51:11 +03:00
Aliaksandr Valialkin
d6523ffe90 Makefile: add -s flag to go fmt in make fmt command 2019-05-25 21:43:35 +03:00
Aliaksandr Valialkin
024560b161 README.md: add goreportcard.com badge 2019-05-25 21:38:57 +03:00
Aliaksandr Valialkin
96ac664b27 Add make victoria-metrics Makefile rule for building dev binary 2019-05-25 18:24:51 +03:00
Aliaksandr Valialkin
2ffcf7a4a5 README.md: mention that VictoriaMetrics is scalable 2019-05-25 17:09:43 +03:00
Aliaksandr Valialkin
5cbd4cfca9 app/vmselect: log slow queries if their execution time exceeds -search.logSlowQueryDuration 2019-05-24 16:12:31 +03:00
Aliaksandr Valialkin
718ce33714 app/vmselect: consume resultsCh data in exportHandler if writeResponseFunc failed to consume it 2019-05-24 14:54:31 +03:00
Aliaksandr Valialkin
f332c0d54e README.md: add contacts chapter 2019-05-24 13:58:26 +03:00
0xflotus
eca566ed22 fixed small errors (#31) 2019-05-24 13:27:42 +03:00
Aliaksandr Valialkin
5bbfdff9fe Makefile: add make publish and make package shortcuts for building and publishing docker images 2019-05-24 13:19:24 +03:00
Aliaksandr Valialkin
6b0ae332f8 lib/encoding: add vm_zstd_block_{compress|decompress}_calls_total for determining the number CompressZSTD / DecompressZSTD calls 2019-05-24 13:01:02 +03:00
Aliaksandr Valialkin
2eb3602d61 app/victoria-metrics: remove -p XXXX:XXXX from docker run options, since it is unnesessary if --net=host is set 2019-05-24 12:54:53 +03:00
Aliaksandr Valialkin
6fb9dd09f5 lib/encoding: add vm_zstd_block_{original|compressed}_bytes_total metrics for rough estimation of block compression ratio 2019-05-24 12:34:32 +03:00
Aliaksandr Valialkin
19b6643e5c lib/encoding: substitute CompressZSTD with CompressZSTDLevel 2019-05-24 12:32:55 +03:00
Aliaksandr Valialkin
08b889ef09 lib/httpserver: add -http.disableResponseCompression flag, which may help saving CPU resources at the cost of higher network bandwidth usage 2019-05-24 12:18:40 +03:00
Aliaksandr Valialkin
d15d0127fe app/vmselect/promql: add alias(q, name) function that sets the given name to all the time series in q 2019-05-24 02:41:45 +03:00
Aliaksandr Valialkin
674888fdc9 lib/decimal: add a comment explaining weird code in maxUpExponent. Fixes #29 2019-05-23 17:18:35 +03:00
Aliaksandr Valialkin
fb140eda33 app/vmselect/promql: add label_transform(q, label, regexp, replacement) function for replacing all the occurences of regexp with replacement in the given label for q 2019-05-23 16:26:19 +03:00
Aliaksandr Valialkin
398ec4383e README.md: typo fix 2019-05-23 02:09:51 +03:00
Aliaksandr Valialkin
eff0debe14 README.md: mention that VictoriaMetrics is high-perf cost-effective TSDB 2019-05-23 00:36:45 +03:00
156 changed files with 10005 additions and 2563 deletions

22
.travis.yml Normal file
View File

@@ -0,0 +1,22 @@
language: go
go:
- 1.12.x
install: make
env:
- GO111MODULE=on
before_install:
- GO111MODULE=off go get -v golang.org/x/lint/golint
- GO111MODULE=off go get -u github.com/kisielk/errcheck
script:
- make check_all
- git diff --exit-code
- make test_full
- make victoria-metrics
after_success:
- bash <(curl -s https://codecov.io/bash)

View File

@@ -19,16 +19,20 @@ include deployment/*/Makefile
clean:
rm -rf bin/*
publish: publish-victoria-metrics
package: package-victoria-metrics
release: victoria-metrics-prod
cd bin && tar czf victoria-metrics-$(PKG_TAG).tar.gz victoria-metrics-prod
fmt:
go fmt $(PKG_PREFIX)/lib/...
go fmt $(PKG_PREFIX)/app/...
GO111MODULE=on gofmt -l -w -s ./lib
GO111MODULE=on gofmt -l -w -s ./app
vet:
go vet $(PKG_PREFIX)/lib/...
go vet $(PKG_PREFIX)/app/...
GO111MODULE=on go vet -mod=vendor ./lib/...
GO111MODULE=on go vet -mod=vendor ./app/...
lint: install-golint
golint lib/...
@@ -46,16 +50,24 @@ errcheck: install-errcheck
install-errcheck:
which errcheck || GO111MODULE=off go get -u github.com/kisielk/errcheck
check_all: fmt vet lint errcheck
test:
go test $(PKG_PREFIX)/lib/...
GO111MODULE=on go test -mod=vendor ./lib/...
GO111MODULE=on go test -mod=vendor ./app/...
test_full:
GO111MODULE=on go test -mod=vendor -coverprofile=coverage.txt -covermode=atomic ./lib/... ./app/...
benchmark:
go test -bench=. $(PKG_PREFIX)/lib/...
GO111MODULE=on go test -mod=vendor -bench=. ./lib/...
GO111MODULE=on go test -mod=vendor -bench=. ./app/...
vendor-update:
go get -u
go mod tidy
go mod vendor
GO111MODULE=on go get -u ./lib/...
GO111MODULE=on go get -u ./app/...
GO111MODULE=on go mod tidy
GO111MODULE=on go mod vendor
quicktemplate-gen: install-qtc
qtc

208
README.md
View File

@@ -1,12 +1,16 @@
<img text-align="center" alt="Victoria Metrics" src="logo.png">
[![Latest Release](https://img.shields.io/github/release/VictoriaMetrics/VictoriaMetrics.svg?style=flat-square)](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/latest)
[![GitHub license](https://img.shields.io/github/license/VictoriaMetrics/VictoriaMetrics.svg)](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/LICENSE)
[![Go Report](https://goreportcard.com/badge/github.com/VictoriaMetrics/VictoriaMetrics)](https://goreportcard.com/report/github.com/VictoriaMetrics/VictoriaMetrics)
[![Build Status](https://travis-ci.org/VictoriaMetrics/VictoriaMetrics.svg?branch=master)](https://travis-ci.org/VictoriaMetrics/VictoriaMetrics)
[![codecov](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/branch/master/graph/badge.svg)](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics)
<img text-align="center" alt="Victoria Metrics" src="logo.png">
## Single-node VictoriaMetrics
[![Latest Release](https://img.shields.io/github/release/VictoriaMetrics/VictoriaMetrics.svg?style=flat-square)](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/latest)
VictoriaMetrics is a long-term remote storage for Prometheus.
VictoriaMetrics is fast, cost-effective and scalable time series database. It can be used as a long-term remote storage for Prometheus.
It is available in [binary releases](https://github.com/VictoriaMetrics/VictoriaMetrics/releases),
[docker images](https://hub.docker.com/r/valyala/victoria-metrics/) and
[docker images](https://hub.docker.com/r/victoriametrics/victoria-metrics/) and
in [source code](https://github.com/VictoriaMetrics/VictoriaMetrics).
Cluster version is available [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/cluster).
@@ -37,7 +41,7 @@ Cluster version is available [here](https://github.com/VictoriaMetrics/VictoriaM
* [Graphite plaintext protocol](https://graphite.readthedocs.io/en/latest/feeding-carbon.html) with [tags](https://graphite.readthedocs.io/en/latest/tags.html#carbon)
if `-graphiteListenAddr` is set.
* [OpenTSDB put message](http://opentsdb.net/docs/build/html/api_telnet/put.html) if `-opentsdbListenAddr` is set.
* Ideally works with big amounts of time series data from IoT sensors, connected car sensors and industrial sensors.
* Ideally works with big amounts of time series data from Kubernetes, IoT sensors, connected cars and industrial telemetry.
* Has open source [cluster version](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/cluster).
@@ -46,34 +50,50 @@ Cluster version is available [here](https://github.com/VictoriaMetrics/VictoriaM
### Table of contents
* [How to build from sources](#how-to-build-from-sources)
* [How to start VictoriaMetrics](#how-to-start-victoriametrics)
* [Prometheus setup](#prometheus-setup)
* [Grafana setup](#grafana-setup)
* [How to send data from InfluxDB-compatible agents such as Telegraf](#how-to-send-data-from-influxdb-compatible-agents-such-as-telegraf)
* [How to send data from Graphite-compatible agents such as StatsD](#how-to-send-data-from-graphite-compatible-agents-such-as-statsd)
* [How to send data from OpenTSDB-compatible agents](#how-to-send-data-from-opentsdb-compatible-agents)
* [How to apply new config / ugrade VictoriaMetrics](#how-to-apply-new-config--upgrade-victoriametrics)
* [How to work with snapshots](#how-to-work-with-snapshots)
* [How to delete time series](#how-to-delete-time-series)
* [How to export time series](#how-to-export-time-series)
* [Federation](#federation)
* [Capacity planning](#capacity-planning)
* [High Availability](#high-availability)
* [Multiple retentions](#multiple-retentions)
* [Scalability and cluster version](#scalability-and-cluster-version)
* [Security](#security)
* [Tuning](#tuning)
* [Monitoring](#monitoring)
* [Troubleshooting](#troubleshooting)
* [Community and contributions](#community-and-contributions)
* [Reporting bugs](#reporting-bugs)
- [Single-node VictoriaMetrics](#single-node-victoriametrics)
- [Prominent features](#prominent-features)
- [Operation](#operation)
- [Table of contents](#table-of-contents)
- [How to build from sources](#how-to-build-from-sources)
- [Development build](#development-build)
- [Production build](#production-build)
- [Building docker images](#building-docker-images)
- [How to start VictoriaMetrics](#how-to-start-victoriametrics)
- [Setting up service](#setting-up-service)
- [Third-party contributions](#third-party-contributions)
- [Prometheus setup](#prometheus-setup)
- [Grafana setup](#grafana-setup)
- [How to send data from InfluxDB-compatible agents such as Telegraf?](#how-to-send-data-from-influxdb-compatible-agents-such-as-telegraf)
- [How to send data from Graphite-compatible agents such as StatsD?](#how-to-send-data-from-graphite-compatible-agents-such-as-statsd)
- [How to send data from OpenTSDB-compatible agents?](#how-to-send-data-from-opentsdb-compatible-agents)
- [How to apply new config / upgrade VictoriaMetrics?](#how-to-apply-new-config--upgrade-victoriametrics)
- [How to work with snapshots?](#how-to-work-with-snapshots)
- [How to delete time series?](#how-to-delete-time-series)
- [How to export time series?](#how-to-export-time-series)
- [Federation](#federation)
- [Capacity planning](#capacity-planning)
- [High availability](#high-availability)
- [Multiple retentions](#multiple-retentions)
- [Downsampling](#downsampling)
- [Scalability and cluster version](#scalability-and-cluster-version)
- [Security](#security)
- [Tuning](#tuning)
- [Monitoring](#monitoring)
- [Troubleshooting](#troubleshooting)
- [Contacts](#contacts)
- [Community and contributions](#community-and-contributions)
- [Reporting bugs](#reporting-bugs)
- [Victoria Metrics Logo](#victoria-metrics-logo)
- [Logo Usage Guidelines](#logo-usage-guidelines)
- [Font used:](#font-used)
- [Color Palette:](#color-palette)
- [We kindly ask:](#we-kindly-ask)
### How to build from sources
We recommend using either [binary releases](https://github.com/VictoriaMetrics/VictoriaMetrics/releases) or
[docker images](https://hub.docker.com/r/valyala/victoria-metrics/) instead of building VictoriaMetrics
[docker images](https://hub.docker.com/r/victoriametrics/victoria-metrics/) instead of building VictoriaMetrics
from sources. Building from sources is reasonable when developing an additional features specific
to your needs.
@@ -81,21 +101,20 @@ to your needs.
#### Development build
1. [Install Go](https://golang.org/doc/install). The minimum supported version is Go 1.12.
2. Run `go build ./app/victoria-metrics` from the root folder of the repository.
It will build `victoria-metrics` binary in the root folder of the repository.
2. Run `make victoria-metrics` from the root folder of the repository.
It will build `victoria-metrics` binary and put it into the `bin` folder.
#### Production build
1. [Install docker](https://docs.docker.com/install/).
2. Run `make victoria-metrics-prod` from the root folder of the respository.
2. Run `make victoria-metrics-prod` from the root folder of the repository.
It will build `victoria-metrics-prod` binary and put it into the `bin` folder.
#### Building docker images
Run `make package-victoria-metrics`. It will build `valyala/victoria-metrics:<PKG_TAG>` docker image locally.
Run `make package-victoria-metrics`. It will build `victoriametrics/victoria-metrics:<PKG_TAG>` docker image locally.
`<PKG_TAG>` is auto-generated image tag, which depends on source code in the repository.
The `<PKG_TAG>` may be manually set via `PKG_TAG=foobar make package`.
The `<PKG_TAG>` may be manually set via `PKG_TAG=foobar make package-victoria-metrics`.
### How to start VictoriaMetrics
@@ -113,6 +132,16 @@ The following command line flags are used the most:
Pass `-help` to see all the available flags with description and default values.
### Setting up service
Read [these instructions](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/43) on how to set up VictoriaMetrics as a service in your OS.
### Third-party contributions
* [Unofficial yum repository](https://copr.fedorainfracloud.org/coprs/antonpatsev/VictoriaMetrics/) ([source code](https://github.com/patsevanton/victoriametrics-rpm))
### Prometheus setup
Add the following lines to Prometheus config file (it is usually located at `/etc/prometheus/prometheus.yml`):
@@ -181,6 +210,38 @@ VictoriaMetrics maps Influx data using the following rules:
* Field values are mapped to time series values
* Tags are mapped to Prometheus labels as-is
For example, the following Influx line:
```
foo,tag1=value1,tag2=value2 field1=12,field2=40
```
is converted into the following Prometheus data points:
```
foo.field1{tag1="value1", tag2="value2"} 12
foo.field2{tag1="value1", tag2="value2"} 40
```
Example for writing data with Influx line protocol to local VictoriaMetrics using `curl`:
```
curl -d 'measurement,tag1=value1,tag2=value2 field1=123,field2=1.23' -X POST 'http://localhost:8428/write'
```
After that the data may be read via [/api/v1/export](#how-to-export-time-series) endpoint:
```
curl -G 'http://localhost:8428/api/v1/export' --data-urlencode 'match={__name__!=""}'
```
The `/api/v1/export` endpoint should return the following response:
```
{"metric":{"__name__":"measurement.field1","tag1":"value1","tag2":"value2"},"values":[123],"timestamps":[1560272508147]}
{"metric":{"__name__":"measurement.field2","tag1":"value1","tag2":"value2"},"values":[1.23],"timestamps":[1560272508147]}
```
### How to send data from Graphite-compatible agents such as [StatsD](https://github.com/etsy/statsd)?
@@ -188,25 +249,63 @@ VictoriaMetrics maps Influx data using the following rules:
the following command will enable Graphite receiver in VictoriaMetrics on TCP and UDP port `2003`:
```
/path/to/victoria-metrics-prod ... -graphiteListenAddr=:2003
/path/to/victoria-metrics-prod -graphiteListenAddr=:2003
```
2) Use the configured address in Graphite-compatible agents. For instance, set `graphiteHost`
to the VictoriaMetrics host in `StatsD` configs.
Example for writing data with Graphite plaintext protocol to local VictoriaMetrics using `nc`:
```
echo "foo.bar.baz;tag1=value1;tag2=value2 123 `date +%s`" | nc -N localhost 2003
```
After that the data may be read via [/api/v1/export](#how-to-export-time-series) endpoint:
```
curl -G 'http://localhost:8428/api/v1/export' --data-urlencode 'match={__name__!=""}'
```
The `/api/v1/export` endpoint should return the following response:
```
{"metric":{"__name__":"foo.bar.baz","tag1":"value1","tag2":"value2"},"values":[123],"timestamps":[1560277406000]}
```
### How to send data from OpenTSDB-compatible agents?
1) Enable OpenTSDB receiver in VictoriaMetrics by setting `-opentsdbListenAddr` command line flag. For instance,
the following command will enable OpenTSDB receiver in VictoriaMetrics on TCP and UDP port `4242`:
```
/path/to/victoria-metrics-prod ... -opentsdbListenAddr=:4242
/path/to/victoria-metrics-prod -opentsdbListenAddr=:4242
```
2) Send data to the given address from OpenTSDB-compatible agents.
Example for writing data with OpenTSDB protocol to local VictoriaMetrics using `nc`:
```
echo "put foo.bar.baz `date +%s` 123 tag1=value1 tag2=value2" | nc -N localhost 4242
```
After that the data may be read via [/api/v1/export](#how-to-export-time-series) endpoint:
```
curl -G 'http://localhost:8428/api/v1/export' --data-urlencode 'match={__name__!=""}'
```
The `/api/v1/export` endpoint should return the following response:
```
{"metric":{"__name__":"foo.bar.baz","tag1":"value1","tag2":"value2"},"values":[123],"timestamps":[1560277292000]}
```
### How to apply new config / upgrade VictoriaMetrics?
VictoriaMetrics must be restarted in order to upgrade or apply new config:
@@ -218,6 +317,8 @@ VictoriaMetrics must be restarted in order to upgrade or apply new config:
### How to work with snapshots?
VictoriaMetrics is able to create [instant snapshots](https://medium.com/@valyala/how-victoriametrics-makes-instant-snapshots-for-multi-terabyte-time-series-data-e1f3fb0e0282)
for all the data stored under `-storageDataPath` directory.
Navigate to `http://<victoriametrics-addr>:8428/snapshot/create` in order to create an instant snapshot.
The page will return the following JSON response:
@@ -226,7 +327,7 @@ The page will return the following JSON response:
```
Snapshots are created under `<-storageDataPath>/snapshots` directory, where `<-storageDataPath>`
is the command-line flag value. Snapshots can be archived to backup storage via `rsync -L`, `scp -r`
is the command-line flag value. Snapshots can be archived to backup storage via `cp -L`, `rsync -L`, `scp -r`
or any similar tool that follows symlinks during copying.
The `http://<victoriametrics-addr>:8428/snapshot/list` page contains the list of available snapshots.
@@ -236,6 +337,12 @@ to delete `<snapshot-name>` snapshot.
Navigate to `http://<victoriametrics-addr>:8428/snapshot/delete_all` in order to delete all the snapshots.
Steps for restoring from a snapshot:
1. Stop VictoriaMetrics with `kill -INT`.
2. Remove the entire contents of the directory pointed by `-storageDataPath` command-line flag.
3. Copy snapshot contents to the directory pointed by `-storageDataPath`.
4. Start VictoriaMetrics.
### How to delete time series?
@@ -268,7 +375,7 @@ at `http://<victoriametrics-addr>:8428/federate?match[]=<timeseries_selector_for
Optional `start` and `end` args may be added to the request in order to scrape the last point for each selected time series on the `[start ... end]` interval.
`start` and `end` may contain either unix timestamp in seconds or [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) values. By default the last point
on the interval `[now - max_lookback ... now]` is scraped for each time series. Default value for `max_lookback` is `5m` (5 minutes), but can be overriden.
on the interval `[now - max_lookback ... now]` is scraped for each time series. Default value for `max_lookback` is `5m` (5 minutes), but can be overridden.
For instance, `/federate?match[]=up&max_lookback=1h` would return last points on the `[now - 1h ... now]` interval. This may be useful for time series federation
with scrape intervals exceeding `5m`.
@@ -325,6 +432,18 @@ Just start multiple VictoriaMetrics instances with distinct values for the follo
* `-httpListenAddr`, so clients may reach VictoriaMetrics instance with proper retention
### Downsampling
There is no downsampling support at the moment, but:
- VictoriaMetrics is optimized for querying big amounts of raw data. See benchmark results for heavy queries
in [this article](https://medium.com/@valyala/measuring-vertical-scalability-for-time-series-databases-in-google-cloud-92550d78d8ae).
- VictoriaMetrics has good compression for on-disk data. See [this article](https://medium.com/@valyala/victoriametrics-achieving-better-compression-for-time-series-data-than-gorilla-317bc1f95932)
for details.
These properties reduce the need in downsampling. We plan implementing downsampling in the future.
See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/36) for details.
### Scalability and cluster version
Though single-node VictoriaMetrics cannot scale to multiple nodes, it is optimized for resource usage - storage size / bandwidth / IOPS, RAM, CPU.
@@ -377,9 +496,18 @@ There is [an official Grafana dashboard for single-node VictoriaMetrics](https:/
option, since too big value for `-memory.allowedPercent` may result in high I/O usage.
## Contacts
Contact us with any questions regarding VictoriaMetrics at [info@victoriametrics.com](mailto:info@victoriametrics.com).
## Community and contributions
Feel free asking any questions regarding VictoriaMetrics [here](https://groups.google.com/forum/#!forum/victorametrics-users).
Feel free asking any questions regarding VictoriaMetrics:
- [telergam-en](https://t.me/VictoriaMetrics_en)
- [telergam-ru](https://t.me/VictoriaMetrics_ru1)
- [google groups](https://groups.google.com/forum/#!forum/victorametrics-users)
We are open to third-party pull requests provided they follow [KISS design principle](https://en.wikipedia.org/wiki/KISS_principle):

View File

@@ -1,5 +1,8 @@
# All these commands must run from repository root.
victoria-metrics:
GO111MODULE=on go build -mod=vendor -ldflags "$(GO_BUILDINFO)" -o bin/victoria-metrics ./app/victoria-metrics
victoria-metrics-prod:
APP_NAME=victoria-metrics $(MAKE) app-via-docker
@@ -12,10 +15,13 @@ publish-victoria-metrics:
run-victoria-metrics:
mkdir -p victoria-metrics-data
DOCKER_OPTS='-v $(shell pwd)/victoria-metrics-data:/victoria-metrics-data -p 8428:8428 -p 2003:2003 -p 2003:2003/udp' \
DOCKER_OPTS='-v $(shell pwd)/victoria-metrics-data:/victoria-metrics-data' \
APP_NAME=victoria-metrics \
ARGS='-graphiteListenAddr=:2003 -opentsdbListenAddr=:4242 -retentionPeriod=12 -search.maxUniqueTimeseries=1000000 -search.maxQueryDuration=10m' \
$(MAKE) run-via-docker
victoria-metrics-arm:
CC=arm-linux-gnueabi-gcc CGO_ENABLED=1 GOARCH=arm GO111MODULE=on go build -mod=vendor -ldflags "$(GO_BUILDINFO)" -o bin/victoria-metrics-arm ./app/victoria-metrics
victoria-metrics-arm64:
CC=aarch64-linux-gnu-gcc CGO_ENABLED=1 GOARCH=arm64 GO111MODULE=on go build -mod=vendor -ldflags "$(GO_BUILDINFO)" -o bin/victoria-metrics-arm64 ./app/victoria-metrics

View File

@@ -30,11 +30,10 @@ func (ctx *InsertCtx) Reset(rowsLen int) {
mr.MetricNameRaw = nil
}
ctx.mrs = ctx.mrs[:0]
if n := rowsLen - cap(ctx.mrs); n > 0 {
ctx.mrs = append(ctx.mrs[:cap(ctx.mrs)], make([]storage.MetricRow, n)...)
}
ctx.mrs = ctx.mrs[:rowsLen]
ctx.mrs = ctx.mrs[:0]
ctx.metricNamesBuf = ctx.metricNamesBuf[:0]
}

View File

@@ -0,0 +1,67 @@
package common
import (
"bytes"
"fmt"
"io"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
)
// The maximum size of a single line returned by ReadLinesBlock.
const maxLineSize = 256 * 1024
// Default size in bytes of a single block returned by ReadLinesBlock.
const defaultBlockSize = 64 * 1024
// ReadLinesBlock reads a block of lines delimited by '\n' from tailBuf and r into dstBuf.
//
// Trailing chars after the last newline are put into tailBuf.
//
// Returns (dstBuf, tailBuf).
func ReadLinesBlock(r io.Reader, dstBuf, tailBuf []byte) ([]byte, []byte, error) {
if cap(dstBuf) < defaultBlockSize {
dstBuf = bytesutil.Resize(dstBuf, defaultBlockSize)
}
dstBuf = append(dstBuf[:0], tailBuf...)
again:
n, err := r.Read(dstBuf[len(dstBuf):cap(dstBuf)])
// Check for error only if zero bytes read from r, i.e. no forward progress made.
// Otherwise process the read data.
if n == 0 {
if err == nil {
return dstBuf, tailBuf, fmt.Errorf("no forward progress made")
}
if err == io.EOF && len(dstBuf) > 0 {
// Missing newline in the end of stream. This is OK,
/// so suppress io.EOF for now. It will be returned during the next
// call to ReadLinesBlock.
// This fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/60 .
return dstBuf, tailBuf, nil
}
return dstBuf, tailBuf, err
}
dstBuf = dstBuf[:len(dstBuf)+n]
// Search for the last newline in dstBuf and put the rest into tailBuf.
nn := bytes.LastIndexByte(dstBuf[len(dstBuf)-n:], '\n')
if nn < 0 {
// Didn't found at least a single line.
if len(dstBuf) > maxLineSize {
return dstBuf, tailBuf, fmt.Errorf("too long line: more than %d bytes", maxLineSize)
}
if cap(dstBuf) < 2*len(dstBuf) {
// Increase dsbBuf capacity, so more data could be read into it.
dstBufLen := len(dstBuf)
dstBuf = bytesutil.Resize(dstBuf, 2*cap(dstBuf))
dstBuf = dstBuf[:dstBufLen]
}
goto again
}
// Found at least a single line. Return it.
nn += len(dstBuf) - n
tailBuf = append(tailBuf[:0], dstBuf[nn+1:]...)
dstBuf = dstBuf[:nn]
return dstBuf, tailBuf, nil
}

View File

@@ -0,0 +1,146 @@
package common
import (
"bytes"
"fmt"
"io"
"testing"
)
func TestReadLinesBlockFailure(t *testing.T) {
f := func(s string) {
t.Helper()
r := bytes.NewBufferString(s)
if _, _, err := ReadLinesBlock(r, nil, nil); err == nil {
t.Fatalf("expecting non-nil error")
}
sbr := &singleByteReader{
b: []byte(s),
}
if _, _, err := ReadLinesBlock(sbr, nil, nil); err == nil {
t.Fatalf("expecting non-nil error")
}
fr := &failureReader{}
if _, _, err := ReadLinesBlock(fr, nil, nil); err == nil {
t.Fatalf("expecting non-nil error")
}
}
// empty string
f("")
// too long string
b := make([]byte, maxLineSize+1)
f(string(b))
}
type failureReader struct{}
func (fr *failureReader) Read(p []byte) (int, error) {
return 0, fmt.Errorf("some error")
}
func TestReadLineBlockSuccessSingleByteReader(t *testing.T) {
f := func(s, dstBufExpected, tailBufExpected string) {
t.Helper()
r := &singleByteReader{
b: []byte(s),
}
dstBuf, tailBuf, err := ReadLinesBlock(r, nil, nil)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
if string(dstBuf) != dstBufExpected {
t.Fatalf("unexpected dstBuf; got %q; want %q; tailBuf=%q", dstBuf, dstBufExpected, tailBuf)
}
if string(tailBuf) != tailBufExpected {
t.Fatalf("unexpected tailBuf; got %q; want %q; dstBuf=%q", tailBuf, tailBufExpected, dstBuf)
}
// Verify the same with non-empty dstBuf and tailBuf
r = &singleByteReader{
b: []byte(s),
}
dstBuf, tailBuf, err = ReadLinesBlock(r, dstBuf, tailBuf[:0])
if err != nil {
t.Fatalf("non-empty bufs: unexpected error: %s", err)
}
if string(dstBuf) != dstBufExpected {
t.Fatalf("non-empty bufs: unexpected dstBuf; got %q; want %q; tailBuf=%q", dstBuf, dstBufExpected, tailBuf)
}
if string(tailBuf) != tailBufExpected {
t.Fatalf("non-empty bufs: unexpected tailBuf; got %q; want %q; dstBuf=%q", tailBuf, tailBufExpected, dstBuf)
}
}
f("\n", "", "")
f("foo\n", "foo", "")
f("\nfoo", "", "")
f("foo\nbar", "foo", "")
f("foo\nbar\nbaz", "foo", "")
f("foo", "foo", "")
// The maximum line size
b := make([]byte, maxLineSize+10)
b[maxLineSize] = '\n'
f(string(b), string(b[:maxLineSize]), "")
}
func TestReadLineBlockSuccessBytesBuffer(t *testing.T) {
f := func(s, dstBufExpected, tailBufExpected string) {
t.Helper()
r := bytes.NewBufferString(s)
dstBuf, tailBuf, err := ReadLinesBlock(r, nil, nil)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
if string(dstBuf) != dstBufExpected {
t.Fatalf("unexpected dstBuf; got %q; want %q; tailBuf=%q", dstBuf, dstBufExpected, tailBuf)
}
if string(tailBuf) != tailBufExpected {
t.Fatalf("unexpected tailBuf; got %q; want %q; dstBuf=%q", tailBuf, tailBufExpected, dstBuf)
}
// Verify the same with non-empty dstBuf and tailBuf
r = bytes.NewBufferString(s)
dstBuf, tailBuf, err = ReadLinesBlock(r, dstBuf, tailBuf[:0])
if err != nil {
t.Fatalf("non-empty bufs: unexpected error: %s", err)
}
if string(dstBuf) != dstBufExpected {
t.Fatalf("non-empty bufs: unexpected dstBuf; got %q; want %q; tailBuf=%q", dstBuf, dstBufExpected, tailBuf)
}
if string(tailBuf) != tailBufExpected {
t.Fatalf("non-empty bufs: unexpected tailBuf; got %q; want %q; dstBuf=%q", tailBuf, tailBufExpected, dstBuf)
}
}
f("\n", "", "")
f("foo\n", "foo", "")
f("\nfoo", "", "foo")
f("foo\nbar", "foo", "bar")
f("foo\nbar\nbaz", "foo\nbar", "baz")
// The maximum line size
b := make([]byte, maxLineSize+10)
b[maxLineSize] = '\n'
f(string(b), string(b[:maxLineSize]), string(b[maxLineSize+1:]))
}
type singleByteReader struct {
b []byte
}
func (sbr *singleByteReader) Read(p []byte) (int, error) {
if len(sbr.b) == 0 {
return 0, io.EOF
}
n := copy(p, sbr.b[:1])
sbr.b = sbr.b[n:]
if len(sbr.b) == 0 {
return n, io.EOF
}
return n, nil
}

View File

@@ -1,34 +1,49 @@
package concurrencylimiter
import (
"flag"
"fmt"
"runtime"
"time"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/timerpool"
"github.com/VictoriaMetrics/metrics"
)
var maxConcurrentInserts = flag.Int("maxConcurrentInserts", runtime.GOMAXPROCS(-1)*4, "The maximum number of concurrent inserts")
var (
// ch is the channel for limiting concurrent inserts.
// Put an item into it before performing an insert and remove
// the item after the insert is complete.
ch = make(chan struct{}, runtime.GOMAXPROCS(-1)*2)
// ch is the channel for limiting concurrent calls to Do.
ch chan struct{}
// waitDuration is the amount of time to wait until at least a single
// concurrent insert out of cap(Ch) inserts is complete.
// concurrent Do call out of cap(ch) inserts is complete.
waitDuration = time.Second * 30
)
// Init initializes concurrencylimiter.
//
// Init must be called after flag.Parse call.
func Init() {
ch = make(chan struct{}, *maxConcurrentInserts)
}
// Do calls f with the limited concurrency.
func Do(f func() error) error {
// Limit the number of conurrent inserts in order to prevent from excess
// Limit the number of conurrent f calls in order to prevent from excess
// memory usage and CPU trashing.
t := time.NewTimer(waitDuration)
t := timerpool.Get(waitDuration)
select {
case ch <- struct{}{}:
t.Stop()
timerpool.Put(t)
err := f()
<-ch
return err
case <-t.C:
return fmt.Errorf("the server is overloaded with %d concurrent inserts; either increase the number of CPUs or reduce the load", cap(ch))
timerpool.Put(t)
concurrencyLimitErrors.Inc()
return fmt.Errorf("the server is overloaded with %d concurrent inserts; either increase -maxConcurrentInserts or reduce the load", cap(ch))
}
}
var concurrencyLimitErrors = metrics.NewCounter(`vm_concurrency_limit_errors_total`)

View File

@@ -1,7 +1,6 @@
package graphite
import (
"bytes"
"fmt"
"io"
"net"
@@ -55,8 +54,6 @@ func (ctx *pushCtx) InsertRows() error {
return ic.FlushBufs()
}
const maxReadPacketSize = 4 * 1024 * 1024
const flushTimeout = 3 * time.Second
func (ctx *pushCtx) Read(r io.Reader) bool {
@@ -71,33 +68,22 @@ func (ctx *pushCtx) Read(r io.Reader) bool {
return false
}
}
lr := io.LimitReader(r, maxReadPacketSize)
ctx.reqBuf.Reset()
ctx.reqBuf.B = append(ctx.reqBuf.B[:0], ctx.tailBuf...)
n, err := io.CopyBuffer(&ctx.reqBuf, lr, ctx.copyBuf[:])
if err != nil {
if ne, ok := err.(net.Error); ok && ne.Timeout() {
ctx.reqBuf, ctx.tailBuf, ctx.err = common.ReadLinesBlock(r, ctx.reqBuf, ctx.tailBuf)
if ctx.err != nil {
if ne, ok := ctx.err.(net.Error); ok && ne.Timeout() {
// Flush the read data on timeout and try reading again.
ctx.err = nil
} else {
graphiteReadErrors.Inc()
ctx.err = fmt.Errorf("cannot read graphite plaintext protocol data: %s", err)
if ctx.err != io.EOF {
graphiteReadErrors.Inc()
ctx.err = fmt.Errorf("cannot read graphite plaintext protocol data: %s", ctx.err)
}
return false
}
} else if n < maxReadPacketSize {
// Mark the end of stream.
ctx.err = io.EOF
}
// Parse all the rows until the last newline in ctx.reqBuf.B
nn := bytes.LastIndexByte(ctx.reqBuf.B, '\n')
ctx.tailBuf = ctx.tailBuf[:0]
if nn >= 0 {
ctx.tailBuf = append(ctx.tailBuf[:0], ctx.reqBuf.B[nn+1:]...)
ctx.reqBuf.B = ctx.reqBuf.B[:nn]
}
if err = ctx.Rows.Unmarshal(bytesutil.ToUnsafeString(ctx.reqBuf.B)); err != nil {
if err := ctx.Rows.Unmarshal(bytesutil.ToUnsafeString(ctx.reqBuf)); err != nil {
graphiteUnmarshalErrors.Inc()
ctx.err = fmt.Errorf("cannot unmarshal graphite plaintext protocol data with size %d: %s", len(ctx.reqBuf.B), err)
ctx.err = fmt.Errorf("cannot unmarshal graphite plaintext protocol data with size %d: %s", len(ctx.reqBuf), err)
return false
}
@@ -112,9 +98,8 @@ type pushCtx struct {
Rows Rows
Common common.InsertCtx
reqBuf bytesutil.ByteBuffer
reqBuf []byte
tailBuf []byte
copyBuf [16 * 1024]byte
err error
}
@@ -129,7 +114,7 @@ func (ctx *pushCtx) Error() error {
func (ctx *pushCtx) reset() {
ctx.Rows.Reset()
ctx.Common.Reset(0)
ctx.reqBuf.Reset()
ctx.reqBuf = ctx.reqBuf[:0]
ctx.tailBuf = ctx.tailBuf[:0]
ctx.err = nil

View File

@@ -293,8 +293,10 @@ func parseFieldValue(s string, hasQuotedFields bool) (float64, error) {
if len(s) < 2 || s[len(s)-1] != '"' {
return 0, fmt.Errorf("missing closing quote for quoted field value %s", s)
}
// Quoted string is translated to empty value.
return 0, nil
// Try converting quoted string to number, since sometimes Influx agents
// send numbers as strings.
s = s[1 : len(s)-1]
return fastfloat.ParseBestEffort(s), nil
}
ch := s[len(s)-1]
if ch == 'i' {

View File

@@ -241,17 +241,27 @@ func TestRowsUnmarshalSuccess(t *testing.T) {
})
// Line with multiple tags, multiple fields and timestamp
f(`system,host=ip-172-16-10-144 uptime_format="3 days, 21:01" 1557761040000000000`, &Rows{
f(`system,host=ip-172-16-10-144 uptime_format="3 days, 21:01",quoted_float="-1.23",quoted_int="123" 1557761040000000000`, &Rows{
Rows: []Row{{
Measurement: "system",
Tags: []Tag{{
Key: "host",
Value: "ip-172-16-10-144",
}},
Fields: []Field{{
Key: "uptime_format",
Value: 0,
}},
Fields: []Field{
{
Key: "uptime_format",
Value: 0,
},
{
Key: "quoted_float",
Value: -1.23,
},
{
Key: "quoted_int",
Value: 123,
},
},
Timestamp: 1557761040000000000,
}},
})

View File

@@ -1,7 +1,6 @@
package influx
import (
"bytes"
"compress/gzip"
"fmt"
"io"
@@ -123,36 +122,21 @@ func putGzipReader(zr *gzip.Reader) {
var gzipReaderPool sync.Pool
const maxReadPacketSize = 4 * 1024 * 1024
func (ctx *pushCtx) Read(r io.Reader, tsMultiplier int64) bool {
if ctx.err != nil {
return false
}
lr := io.LimitReader(r, maxReadPacketSize)
ctx.reqBuf.Reset()
ctx.reqBuf.B = append(ctx.reqBuf.B[:0], ctx.tailBuf...)
n, err := io.CopyBuffer(&ctx.reqBuf, lr, ctx.copyBuf[:])
if err != nil {
influxReadErrors.Inc()
ctx.err = fmt.Errorf("cannot read influx line protocol data: %s", err)
ctx.reqBuf, ctx.tailBuf, ctx.err = common.ReadLinesBlock(r, ctx.reqBuf, ctx.tailBuf)
if ctx.err != nil {
if ctx.err != io.EOF {
influxReadErrors.Inc()
ctx.err = fmt.Errorf("cannot read influx line protocol data: %s", ctx.err)
}
return false
}
if n < maxReadPacketSize {
// Mark the end of stream.
ctx.err = io.EOF
}
// Parse all the rows until the last newline in ctx.reqBuf.B
nn := bytes.LastIndexByte(ctx.reqBuf.B, '\n')
ctx.tailBuf = ctx.tailBuf[:0]
if nn >= 0 {
ctx.tailBuf = append(ctx.tailBuf[:0], ctx.reqBuf.B[nn+1:]...)
ctx.reqBuf.B = ctx.reqBuf.B[:nn]
}
if err = ctx.Rows.Unmarshal(bytesutil.ToUnsafeString(ctx.reqBuf.B)); err != nil {
if err := ctx.Rows.Unmarshal(bytesutil.ToUnsafeString(ctx.reqBuf)); err != nil {
influxUnmarshalErrors.Inc()
ctx.err = fmt.Errorf("cannot unmarshal influx line protocol data with size %d: %s", len(ctx.reqBuf.B), err)
ctx.err = fmt.Errorf("cannot unmarshal influx line protocol data with size %d: %s", len(ctx.reqBuf), err)
return false
}
@@ -191,9 +175,8 @@ type pushCtx struct {
Rows Rows
Common common.InsertCtx
reqBuf bytesutil.ByteBuffer
reqBuf []byte
tailBuf []byte
copyBuf [16 * 1024]byte
metricNameBuf []byte
metricGroupBuf []byte
@@ -211,7 +194,7 @@ func (ctx *pushCtx) reset() {
ctx.Rows.Reset()
ctx.Common.Reset(0)
ctx.reqBuf.Reset()
ctx.reqBuf = ctx.reqBuf[:0]
ctx.tailBuf = ctx.tailBuf[:0]
ctx.metricNameBuf = ctx.metricNameBuf[:0]
ctx.metricGroupBuf = ctx.metricGroupBuf[:0]

View File

@@ -6,6 +6,7 @@ import (
"net/http"
"strings"
"github.com/VictoriaMetrics/VictoriaMetrics/app/vminsert/concurrencylimiter"
"github.com/VictoriaMetrics/VictoriaMetrics/app/vminsert/graphite"
"github.com/VictoriaMetrics/VictoriaMetrics/app/vminsert/influx"
"github.com/VictoriaMetrics/VictoriaMetrics/app/vminsert/opentsdb"
@@ -22,6 +23,7 @@ var (
// Init initializes vminsert.
func Init() {
concurrencylimiter.Init()
if len(*graphiteListenAddr) > 0 {
go graphite.Serve(*graphiteListenAddr)
}
@@ -63,7 +65,8 @@ func RequestHandler(w http.ResponseWriter, r *http.Request) bool {
w.WriteHeader(http.StatusNoContent)
return true
case "/query":
// Emulate fake response for influx query
// Emulate fake response for influx query.
// This is required for TSBS benchmark.
influxQueryRequests.Inc()
fmt.Fprintf(w, `{"results":[{"series":[{"values":[]}]}]}`)
return true

View File

@@ -1,7 +1,6 @@
package opentsdb
import (
"bytes"
"fmt"
"io"
"net"
@@ -71,33 +70,22 @@ func (ctx *pushCtx) Read(r io.Reader) bool {
return false
}
}
lr := io.LimitReader(r, maxReadPacketSize)
ctx.reqBuf.Reset()
ctx.reqBuf.B = append(ctx.reqBuf.B[:0], ctx.tailBuf...)
n, err := io.CopyBuffer(&ctx.reqBuf, lr, ctx.copyBuf[:])
if err != nil {
if ne, ok := err.(net.Error); ok && ne.Timeout() {
ctx.reqBuf, ctx.tailBuf, ctx.err = common.ReadLinesBlock(r, ctx.reqBuf, ctx.tailBuf)
if ctx.err != nil {
if ne, ok := ctx.err.(net.Error); ok && ne.Timeout() {
// Flush the read data on timeout and try reading again.
ctx.err = nil
} else {
opentsdbReadErrors.Inc()
ctx.err = fmt.Errorf("cannot read OpenTSDB put protocol data: %s", err)
if ctx.err != io.EOF {
opentsdbReadErrors.Inc()
ctx.err = fmt.Errorf("cannot read OpenTSDB put protocol data: %s", ctx.err)
}
return false
}
} else if n < maxReadPacketSize {
// Mark the end of stream.
ctx.err = io.EOF
}
// Parse all the rows until the last newline in ctx.reqBuf.B
nn := bytes.LastIndexByte(ctx.reqBuf.B, '\n')
ctx.tailBuf = ctx.tailBuf[:0]
if nn >= 0 {
ctx.tailBuf = append(ctx.tailBuf[:0], ctx.reqBuf.B[nn+1:]...)
ctx.reqBuf.B = ctx.reqBuf.B[:nn]
}
if err = ctx.Rows.Unmarshal(bytesutil.ToUnsafeString(ctx.reqBuf.B)); err != nil {
if err := ctx.Rows.Unmarshal(bytesutil.ToUnsafeString(ctx.reqBuf)); err != nil {
opentsdbUnmarshalErrors.Inc()
ctx.err = fmt.Errorf("cannot unmarshal OpenTSDB put protocol data with size %d: %s", len(ctx.reqBuf.B), err)
ctx.err = fmt.Errorf("cannot unmarshal OpenTSDB put protocol data with size %d: %s", len(ctx.reqBuf), err)
return false
}
@@ -112,9 +100,8 @@ type pushCtx struct {
Rows Rows
Common common.InsertCtx
reqBuf bytesutil.ByteBuffer
reqBuf []byte
tailBuf []byte
copyBuf [16 * 1024]byte
err error
}
@@ -129,7 +116,7 @@ func (ctx *pushCtx) Error() error {
func (ctx *pushCtx) reset() {
ctx.Rows.Reset()
ctx.Common.Reset(0)
ctx.reqBuf.Reset()
ctx.reqBuf = ctx.reqBuf[:0]
ctx.tailBuf = ctx.tailBuf[:0]
ctx.err = nil

View File

@@ -14,6 +14,7 @@ import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fs"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/timerpool"
"github.com/VictoriaMetrics/metrics"
)
@@ -42,13 +43,14 @@ func Stop() {
// RequestHandler handles remote read API requests for Prometheus
func RequestHandler(w http.ResponseWriter, r *http.Request) bool {
// Limit the number of concurrent queries.
// Sleep for a second until giving up. This should resolve short bursts in requests.
t := time.NewTimer(*maxQueueDuration)
// Sleep for a while until giving up. This should resolve short bursts in requests.
t := timerpool.Get(*maxQueueDuration)
select {
case concurrencyCh <- struct{}{}:
t.Stop()
timerpool.Put(t)
defer func() { <-concurrencyCh }()
case <-t.C:
timerpool.Put(t)
httpserver.Errorf(w, "cannot handle more than %d concurrent requests", cap(concurrencyCh))
return true
}
@@ -115,6 +117,15 @@ func RequestHandler(w http.ResponseWriter, r *http.Request) bool {
return true
}
return true
case "/api/v1/labels/count":
labelsCountRequests.Inc()
httpserver.EnableCORS(w, r)
if err := prometheus.LabelsCountHandler(w, r); err != nil {
labelsCountErrors.Inc()
sendPrometheusError(w, r, err)
return true
}
return true
case "/api/v1/export":
exportRequests.Inc()
if err := prometheus.ExportHandler(w, r); err != nil {
@@ -178,6 +189,9 @@ var (
labelsRequests = metrics.NewCounter(`vm_http_requests_total{path="/api/v1/labels"}`)
labelsErrors = metrics.NewCounter(`vm_http_request_errors_total{path="/api/v1/labels"}`)
labelsCountRequests = metrics.NewCounter(`vm_http_requests_total{path="/api/v1/labels/count"}`)
labelsCountErrors = metrics.NewCounter(`vm_http_request_errors_total{path="/api/v1/labels/count"}`)
deleteRequests = metrics.NewCounter(`vm_http_requests_total{path="/api/v1/admin/tsdb/delete_series"}`)
deleteErrors = metrics.NewCounter(`vm_http_request_errors_total{path="/api/v1/admin/tsdb/delete_series"}`)

View File

@@ -400,6 +400,36 @@ func GetLabelValues(labelName string, deadline Deadline) ([]string, error) {
return labelValues, nil
}
// GetLabelEntries returns all the label entries until the given deadline.
func GetLabelEntries(deadline Deadline) ([]storage.TagEntry, error) {
labelEntries, err := vmstorage.SearchTagEntries(*maxTagKeysPerSearch, *maxTagValuesPerSearch)
if err != nil {
return nil, fmt.Errorf("error during label entries request: %s", err)
}
// Substitute "" with "__name__"
for i := range labelEntries {
e := &labelEntries[i]
if e.Key == "" {
e.Key = "__name__"
}
}
// Sort labelEntries by the number of label values in each entry.
sort.Slice(labelEntries, func(i, j int) bool {
a, b := labelEntries[i].Values, labelEntries[j].Values
if len(a) < len(b) {
return true
}
if len(a) > len(b) {
return false
}
return labelEntries[i].Key < labelEntries[j].Key
})
return labelEntries, nil
}
// GetSeriesCount returns the number of unique series.
func GetSeriesCount(deadline Deadline) (uint64, error) {
n, err := vmstorage.GetSeriesCount()

View File

@@ -22,9 +22,7 @@ func InitTmpBlocksDir(tmpDirPath string) {
tmpDirPath = os.TempDir()
}
tmpBlocksDir = tmpDirPath + "/searchResults"
if err := os.RemoveAll(tmpBlocksDir); err != nil {
logger.Panicf("FATAL: cannot remove %q: %s", tmpBlocksDir, err)
}
fs.MustRemoveAll(tmpBlocksDir)
if err := fs.MkdirAllIfNotExist(tmpBlocksDir); err != nil {
logger.Panicf("FATAL: cannot create %q: %s", tmpBlocksDir, err)
}

View File

@@ -0,0 +1,17 @@
{% import "github.com/VictoriaMetrics/VictoriaMetrics/lib/storage" %}
{% stripspace %}
LabelsCountResponse generates response for /api/v1/labels/count .
{% func LabelsCountResponse(labelEntries []storage.TagEntry) %}
{
"status":"success",
"data":{
{% for i, e := range labelEntries %}
{%q= e.Key %}:{%d= len(e.Values) %}
{% if i+1 < len(labelEntries) %},{% endif %}
{% endfor %}
}
}
{% endfunc %}
{% endstripspace %}

View File

@@ -0,0 +1,74 @@
// Code generated by qtc from "labels_count_response.qtpl". DO NOT EDIT.
// See https://github.com/valyala/quicktemplate for details.
//line app/vmselect/prometheus/labels_count_response.qtpl:1
package prometheus
//line app/vmselect/prometheus/labels_count_response.qtpl:1
import "github.com/VictoriaMetrics/VictoriaMetrics/lib/storage"
// LabelsCountResponse generates response for /api/v1/labels/count .
//line app/vmselect/prometheus/labels_count_response.qtpl:5
import (
qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate"
)
//line app/vmselect/prometheus/labels_count_response.qtpl:5
var (
_ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer
)
//line app/vmselect/prometheus/labels_count_response.qtpl:5
func StreamLabelsCountResponse(qw422016 *qt422016.Writer, labelEntries []storage.TagEntry) {
//line app/vmselect/prometheus/labels_count_response.qtpl:5
qw422016.N().S(`{"status":"success","data":{`)
//line app/vmselect/prometheus/labels_count_response.qtpl:9
for i, e := range labelEntries {
//line app/vmselect/prometheus/labels_count_response.qtpl:10
qw422016.N().Q(e.Key)
//line app/vmselect/prometheus/labels_count_response.qtpl:10
qw422016.N().S(`:`)
//line app/vmselect/prometheus/labels_count_response.qtpl:10
qw422016.N().D(len(e.Values))
//line app/vmselect/prometheus/labels_count_response.qtpl:11
if i+1 < len(labelEntries) {
//line app/vmselect/prometheus/labels_count_response.qtpl:11
qw422016.N().S(`,`)
//line app/vmselect/prometheus/labels_count_response.qtpl:11
}
//line app/vmselect/prometheus/labels_count_response.qtpl:12
}
//line app/vmselect/prometheus/labels_count_response.qtpl:12
qw422016.N().S(`}}`)
//line app/vmselect/prometheus/labels_count_response.qtpl:15
}
//line app/vmselect/prometheus/labels_count_response.qtpl:15
func WriteLabelsCountResponse(qq422016 qtio422016.Writer, labelEntries []storage.TagEntry) {
//line app/vmselect/prometheus/labels_count_response.qtpl:15
qw422016 := qt422016.AcquireWriter(qq422016)
//line app/vmselect/prometheus/labels_count_response.qtpl:15
StreamLabelsCountResponse(qw422016, labelEntries)
//line app/vmselect/prometheus/labels_count_response.qtpl:15
qt422016.ReleaseWriter(qw422016)
//line app/vmselect/prometheus/labels_count_response.qtpl:15
}
//line app/vmselect/prometheus/labels_count_response.qtpl:15
func LabelsCountResponse(labelEntries []storage.TagEntry) string {
//line app/vmselect/prometheus/labels_count_response.qtpl:15
qb422016 := qt422016.AcquireByteBuffer()
//line app/vmselect/prometheus/labels_count_response.qtpl:15
WriteLabelsCountResponse(qb422016, labelEntries)
//line app/vmselect/prometheus/labels_count_response.qtpl:15
qs422016 := string(qb422016.B)
//line app/vmselect/prometheus/labels_count_response.qtpl:15
qt422016.ReleaseByteBuffer(qb422016)
//line app/vmselect/prometheus/labels_count_response.qtpl:15
return qs422016
//line app/vmselect/prometheus/labels_count_response.qtpl:15
}

View File

@@ -37,9 +37,18 @@ func FederateHandler(w http.ResponseWriter, r *http.Request) error {
return fmt.Errorf("cannot parse request form values: %s", err)
}
matches := r.Form["match[]"]
maxLookback := getDuration(r, "max_lookback", defaultStep)
start := getTime(r, "start", ct-maxLookback)
end := getTime(r, "end", ct)
maxLookback, err := getDuration(r, "max_lookback", defaultStep)
if err != nil {
return err
}
start, err := getTime(r, "start", ct-maxLookback)
if err != nil {
return err
}
end, err := getTime(r, "end", ct)
if err != nil {
return err
}
deadline := getDeadline(r)
if start >= end {
start = end - defaultStep
@@ -99,8 +108,14 @@ func ExportHandler(w http.ResponseWriter, r *http.Request) error {
match := r.FormValue("match")
matches = []string{match}
}
start := getTime(r, "start", 0)
end := getTime(r, "end", ct)
start, err := getTime(r, "start", 0)
if err != nil {
return err
}
end, err := getTime(r, "end", ct)
if err != nil {
return err
}
format := r.FormValue("format")
deadline := getDeadline(r)
if start >= end {
@@ -156,6 +171,11 @@ func exportHandler(w http.ResponseWriter, matches []string, start, end int64, fo
w.Header().Set("Content-Type", contentType)
writeResponseFunc(w, resultsCh)
// Consume all the data from resultsCh in the event writeResponseFunc
// fails to consume all the data.
for bb := range resultsCh {
quicktemplate.ReleaseByteBuffer(bb)
}
err = <-doneCh
if err != nil {
return fmt.Errorf("error during data fetching: %s", err)
@@ -214,6 +234,23 @@ func LabelValuesHandler(labelName string, w http.ResponseWriter, r *http.Request
var labelValuesDuration = metrics.NewSummary(`vm_request_duration_seconds{path="/api/v1/label/{}/values"}`)
// LabelsCountHandler processes /api/v1/labels/count request.
func LabelsCountHandler(w http.ResponseWriter, r *http.Request) error {
startTime := time.Now()
deadline := getDeadline(r)
labelEntries, err := netstorage.GetLabelEntries(deadline)
if err != nil {
return fmt.Errorf(`cannot obtain label entries: %s`, err)
}
w.Header().Set("Content-Type", "application/json")
WriteLabelsCountResponse(w, labelEntries)
labelsCountDuration.UpdateDuration(startTime)
return nil
}
var labelsCountDuration = metrics.NewSummary(`vm_request_duration_seconds{path="/api/v1/labels/count"}`)
// LabelsHandler processes /api/v1/labels request.
//
// See https://prometheus.io/docs/prometheus/latest/querying/api/#getting-label-names
@@ -260,8 +297,14 @@ func SeriesHandler(w http.ResponseWriter, r *http.Request) error {
return fmt.Errorf("cannot parse form values: %s", err)
}
matches := r.Form["match[]"]
start := getTime(r, "start", ct-defaultStep)
end := getTime(r, "end", ct)
start, err := getTime(r, "start", ct-defaultStep)
if err != nil {
return err
}
end, err := getTime(r, "end", ct)
if err != nil {
return err
}
deadline := getDeadline(r)
tagFilterss, err := getTagFilterssFromMatches(matches)
@@ -297,11 +340,10 @@ func SeriesHandler(w http.ResponseWriter, r *http.Request) error {
WriteSeriesResponse(w, resultsCh)
// Consume all the data from resultsCh in the event WriteSeriesResponse
// fail to consume all the data.
// fails to consume all the data.
for bb := range resultsCh {
quicktemplate.ReleaseByteBuffer(bb)
}
err = <-doneCh
if err != nil {
return fmt.Errorf("error during data fetching: %s", err)
@@ -320,8 +362,14 @@ func QueryHandler(w http.ResponseWriter, r *http.Request) error {
ct := currentTime()
query := r.FormValue("query")
start := getTime(r, "time", ct)
step := getDuration(r, "step", latencyOffset)
start, err := getTime(r, "time", ct)
if err != nil {
return err
}
step, err := getDuration(r, "step", latencyOffset)
if err != nil {
return err
}
deadline := getDeadline(r)
if len(query) > *maxQueryLen {
@@ -384,9 +432,18 @@ func QueryRangeHandler(w http.ResponseWriter, r *http.Request) error {
ct := currentTime()
query := r.FormValue("query")
start := getTime(r, "start", ct-defaultStep)
end := getTime(r, "end", ct)
step := getDuration(r, "step", defaultStep)
start, err := getTime(r, "start", ct-defaultStep)
if err != nil {
return err
}
end, err := getTime(r, "end", ct)
if err != nil {
return err
}
step, err := getDuration(r, "step", defaultStep)
if err != nil {
return err
}
deadline := getDeadline(r)
mayCache := !getBool(r, "nocache")
@@ -463,25 +520,25 @@ func adjustLastPoints(tss []netstorage.Result) {
}
}
func getTime(r *http.Request, argKey string, defaultValue int64) int64 {
func getTime(r *http.Request, argKey string, defaultValue int64) (int64, error) {
argValue := r.FormValue(argKey)
if len(argValue) == 0 {
return defaultValue
return defaultValue, nil
}
secs, err := strconv.ParseFloat(argValue, 64)
if err != nil {
// Try parsing string format
t, err := time.Parse(time.RFC3339, argValue)
if err != nil {
return defaultValue
return 0, fmt.Errorf("cannot parse %q=%q: %s", argKey, argValue, err)
}
secs = float64(t.UnixNano()) / 1e9
}
msecs := int64(secs * 1e3)
if msecs < minTimeMsecs || msecs > maxTimeMsecs {
return defaultValue
return 0, fmt.Errorf("%q=%dms is out of allowed range [%d ... %d]", argKey, msecs, minTimeMsecs, maxTimeMsecs)
}
return msecs
return msecs, nil
}
const (
@@ -490,31 +547,34 @@ const (
maxTimeMsecs = int64(1<<63-1) / 1e6
)
func getDuration(r *http.Request, argKey string, defaultValue int64) int64 {
func getDuration(r *http.Request, argKey string, defaultValue int64) (int64, error) {
argValue := r.FormValue(argKey)
if len(argValue) == 0 {
return defaultValue
return defaultValue, nil
}
secs, err := strconv.ParseFloat(argValue, 64)
if err != nil {
// Try parsing string format
d, err := time.ParseDuration(argValue)
if err != nil {
return defaultValue
return 0, fmt.Errorf("cannot parse %q=%q: %s", argKey, argValue, err)
}
secs = d.Seconds()
}
msecs := int64(secs * 1e3)
if msecs <= 0 || msecs > maxDurationMsecs {
return defaultValue
return 0, fmt.Errorf("%q=%dms is out of allowed range [%d ... %d]", argKey, msecs, 0, maxDurationMsecs)
}
return msecs
return msecs, nil
}
const maxDurationMsecs = 100 * 365 * 24 * 3600 * 1000
func getDeadline(r *http.Request) netstorage.Deadline {
d := getDuration(r, "timeout", 0)
d, err := getDuration(r, "timeout", 0)
if err != nil {
d = 0
}
dMax := int64(maxQueryDuration.Seconds() * 1e3)
if d <= 0 || d > dMax {
d = dMax

View File

@@ -100,10 +100,18 @@ func aggrFuncExt(afe func(tss []*timeseries) []*timeseries, argOrig []*timeserie
}
bbPool.Put(bb)
srcTssCount := 0
dstTssCount := 0
rvs := make([]*timeseries, 0, len(m))
for _, tss := range m {
rv := afe(tss)
rvs = append(rvs, rv...)
srcTssCount += len(tss)
dstTssCount += len(rv)
if dstTssCount > 2000 && dstTssCount > 16*srcTssCount {
// This looks like count_values explosion.
return nil, fmt.Errorf(`too many timeseries after aggragation; got %d; want less than %d`, dstTssCount, 16*srcTssCount)
}
}
return rvs, nil
}
@@ -301,6 +309,9 @@ func aggrFuncCountValues(afa *aggrFuncArg) ([]*timeseries, error) {
m := make(map[float64]bool)
for _, ts := range tss {
for _, v := range ts.Values {
if math.IsNaN(v) {
continue
}
m[v] = true
}
}
@@ -313,7 +324,7 @@ func aggrFuncCountValues(afa *aggrFuncArg) ([]*timeseries, error) {
var rvs []*timeseries
for _, v := range values {
var dst timeseries
dst.CopyFrom(tss[0])
dst.CopyFromShallowTimestamps(tss[0])
dst.MetricName.RemoveTag(dstLabel)
dst.MetricName.AddTag(dstLabel, strconv.FormatFloat(v, 'g', -1, 64))
for i := range dst.Values {
@@ -457,6 +468,7 @@ func newAggrQuantileFunc(phis []float64) func(tss []*timeseries) []*timeseries {
idx := int(math.Round(float64(len(tss)-1) * phi))
dst.Values[n] = tss[idx].Values[n]
}
tss[0] = dst
return tss[:1]
}
}

View File

@@ -0,0 +1,3 @@
package promql
const maxByteSliceLen = 1 << 40

View File

@@ -296,7 +296,8 @@ func adjustBinaryOpTags(be *binaryOpExpr, left, right []*timeseries) ([]*timeser
if len(tss) == 1 {
return nil
}
return fmt.Errorf(`duplicate timeseries on the %s side of %q: %s %s`, side, be.Op, stringMetricTags(&tss[0].MetricName), be.GroupModifier.AppendString(nil))
return fmt.Errorf(`duplicate timeseries on the %s side of %s %s: %s and %s`, side, be.Op, be.GroupModifier.AppendString(nil),
stringMetricTags(&tss[0].MetricName), stringMetricTags(&tss[1].MetricName))
}
var rvsLeft, rvsRight []*timeseries
mLeft, mRight := createTimeseriesMapByTagSet(be, left, right)

View File

@@ -19,7 +19,7 @@ var (
maxPointsPerTimeseries = flag.Int("search.maxPointsPerTimeseries", 10e3, "The maximum points per a single timeseries returned from the search")
)
// The minumum number of points per timeseries for enabling time rounding.
// The minimum number of points per timeseries for enabling time rounding.
// This improves cache hit ratio for frequently requested queries over
// big time ranges.
const minTimeseriesPointsForTimeRounding = 50

View File

@@ -1,16 +1,21 @@
package promql
import (
"flag"
"fmt"
"math"
"sort"
"sync"
"sync/atomic"
"time"
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/netstorage"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
"github.com/VictoriaMetrics/metrics"
)
var logSlowQueryDuration = flag.Duration("search.logSlowQueryDuration", 5*time.Second, "Log queries with execution time exceeding this value. Zero disables slow query logging")
// ExpandWithExprs expands WITH expressions inside q and returns the resulting
// PromQL without WITH expressions.
func ExpandWithExprs(q string) (string, error) {
@@ -24,6 +29,16 @@ func ExpandWithExprs(q string) (string, error) {
// Exec executes q for the given ec until the deadline.
func Exec(ec *EvalConfig, q string) ([]netstorage.Result, error) {
if *logSlowQueryDuration > 0 {
startTime := time.Now()
defer func() {
d := time.Since(startTime)
if d >= *logSlowQueryDuration {
logger.Infof("slow query: duration=%s, start=%d, end=%d, step=%d, query=%q", d, ec.Start/1000, ec.End/1000, ec.Step/1000, q)
}
}()
}
ec.validate()
e, err := parsePromQLWithCache(q)

View File

@@ -789,6 +789,18 @@ func TestExecSuccess(t *testing.T) {
resultExpected := []netstorage.Result{}
f(q, resultExpected)
})
t.Run(`alias()`, func(t *testing.T) {
t.Parallel()
q := `alias(time(), "foobar")`
r := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{1000, 1200, 1400, 1600, 1800, 2000},
Timestamps: timestampsExpected,
}
r.MetricName.MetricGroup = []byte("foobar")
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`label_set(tag)`, func(t *testing.T) {
t.Parallel()
q := `label_set(time(), "tagname", "tagvalue")`
@@ -1266,6 +1278,34 @@ func TestExecSuccess(t *testing.T) {
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`label_transform(mismatch)`, func(t *testing.T) {
t.Parallel()
q := `label_transform(time(), "__name__", "foobar", "xx")`
r := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{1000, 1200, 1400, 1600, 1800, 2000},
Timestamps: timestampsExpected,
}
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`label_transform(match)`, func(t *testing.T) {
t.Parallel()
q := `label_transform(
label_set(time(), "foo", "a.bar.baz"),
"foo", "\\.", "-")`
r := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{1000, 1200, 1400, 1600, 1800, 2000},
Timestamps: timestampsExpected,
}
r.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("a-bar-baz"),
}}
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`label_replace(mismatch)`, func(t *testing.T) {
t.Parallel()
q := `label_replace(time(), "__name__", "x${1}y", "foo", ".+")`
@@ -3461,6 +3501,7 @@ func TestExecError(t *testing.T) {
f(`hour(1,2)`)
f(`label_join()`)
f(`label_replace(1)`)
f(`label_transform(1)`)
f(`label_set()`)
f(`label_set(1, "foo")`)
f(`label_del()`)
@@ -3506,6 +3547,9 @@ func TestExecError(t *testing.T) {
f(`keep_last_value()`)
f(`distinct_over_time()`)
f(`distinct()`)
f(`alias()`)
f(`alias(1)`)
f(`alias(1, "foo", "bar")`)
// Invalid argument type
f(`median_over_time({}, 2)`)
@@ -3535,6 +3579,11 @@ func TestExecError(t *testing.T) {
f(`label_replace(1, "foo", "bar", 4, 5)`)
f(`label_replace(1, "foo", "bar", "baz", 5)`)
f(`label_replace(1, "foo", "bar", "baz", "invalid(regexp")`)
f(`label_transform(1, 2, 3, 4)`)
f(`label_transform(1, "foo", 3, 4)`)
f(`label_transform(1, "foo", "bar", 4)`)
f(`label_transform(1, "foo", "invalid(regexp", "baz`)
f(`alias(1, 2)`)
// Duplicate timeseries
f(`(label_set(1, "foo", "bar") or label_set(2, "foo", "baz"))

View File

@@ -4,6 +4,8 @@ import (
"fmt"
"strconv"
"strings"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
)
type lexer struct {
@@ -85,10 +87,7 @@ again:
goto tokenFoundLabel
}
if isIdentPrefix(s) {
token, err = scanIdent(s)
if err != nil {
return "", err
}
token = scanIdent(s)
goto tokenFoundLabel
}
if isStringPrefix(s) {
@@ -210,15 +209,103 @@ func scanPositiveNumber(s string) (string, error) {
return s[:j], nil
}
func scanIdent(s string) (string, error) {
if len(s) == 0 {
return "", fmt.Errorf("ident cannot be empty")
}
func scanIdent(s string) string {
i := 0
for i < len(s) && isIdentChar(s[i]) {
i++
for i < len(s) {
if isIdentChar(s[i]) {
i++
continue
}
if s[i] != '\\' {
break
}
// Do not verify the next char, since it is escaped.
i += 2
if i > len(s) {
i--
break
}
}
return s[:i], nil
if i == 0 {
logger.Panicf("BUG: scanIdent couldn't find a single ident char; make sure isIdentPrefix called before scanIdent")
}
return s[:i]
}
func unescapeIdent(s string) string {
n := strings.IndexByte(s, '\\')
if n < 0 {
return s
}
dst := make([]byte, 0, len(s))
for {
dst = append(dst, s[:n]...)
s = s[n+1:]
if len(s) == 0 {
return string(dst)
}
if s[0] == 'x' && len(s) >= 3 {
h1 := fromHex(s[1])
h2 := fromHex(s[2])
if h1 >= 0 && h2 >= 0 {
dst = append(dst, byte((h1<<4)|h2))
s = s[3:]
} else {
dst = append(dst, s[0])
s = s[1:]
}
} else {
dst = append(dst, s[0])
s = s[1:]
}
n = strings.IndexByte(s, '\\')
if n < 0 {
dst = append(dst, s...)
return string(dst)
}
}
}
func fromHex(ch byte) int {
if ch >= '0' && ch <= '9' {
return int(ch - '0')
}
if ch >= 'a' && ch <= 'f' {
return int((ch - 'a') + 10)
}
if ch >= 'A' && ch <= 'F' {
return int((ch - 'A') + 10)
}
return -1
}
func toHex(n byte) byte {
if n < 10 {
return '0' + n
}
return 'a' + (n - 10)
}
func appendEscapedIdent(dst, s []byte) []byte {
for i := 0; i < len(s); i++ {
ch := s[i]
if isIdentChar(ch) {
if i == 0 && !isFirstIdentChar(ch) {
// hex-encode the first char
dst = append(dst, '\\', 'x', toHex(ch>>4), toHex(ch&0xf))
} else {
dst = append(dst, ch)
}
} else if ch >= 0x20 && ch < 0x7f {
// Leave ASCII printable chars as is
dst = append(dst, '\\', ch)
} else {
// hex-encode non-printable chars
dst = append(dst, '\\', 'x', toHex(ch>>4), toHex(ch&0xf))
}
}
return dst
}
func (lex *lexer) Prev() {
@@ -353,6 +440,10 @@ func isIdentPrefix(s string) bool {
if len(s) == 0 {
return false
}
if s[0] == '\\' {
// Assume this is an escape char for the next char.
return true
}
return isFirstIdentChar(s[0])
}
@@ -367,7 +458,7 @@ func isIdentChar(ch byte) bool {
if isFirstIdentChar(ch) {
return true
}
return isDecimalChar(ch) || ch == ':' || ch == '.'
return isDecimalChar(ch) || ch == '.'
}
func isSpaceChar(ch byte) bool {

View File

@@ -5,6 +5,57 @@ import (
"testing"
)
func TestUnescapeIdent(t *testing.T) {
f := func(s, resultExpected string) {
t.Helper()
result := unescapeIdent(s)
if result != resultExpected {
t.Fatalf("unexpected result for unescapeIdent(%q); got %q; want %q", s, result, resultExpected)
}
}
f("", "")
f("a", "a")
f("\\", "")
f(`\\`, `\`)
f(`\foo\-bar`, `foo-bar`)
f(`a\\\\b\"c\d`, `a\\b"cd`)
f(`foo.bar:baz_123`, `foo.bar:baz_123`)
f(`foo\ bar`, `foo bar`)
f(`\x21`, `!`)
f(`\xeDfoo\x2Fbar\-\xqw\x`, "\xedfoo\x2fbar-xqwx")
}
func TestAppendEscapedIdent(t *testing.T) {
f := func(s, resultExpected string) {
t.Helper()
result := appendEscapedIdent(nil, []byte(s))
if string(result) != resultExpected {
t.Fatalf("unexpected result for appendEscapedIdent(%q); got %q; want %q", s, result, resultExpected)
}
}
f(`a`, `a`)
f(`a.b:c_23`, `a.b:c_23`)
f(`a b-cd+dd\`, `a\ b\-cd\+dd\\`)
f("a\x1E\x20\xee", `a\x1e\ \xee`)
f("\x2e\x2e", `\x2e.`)
}
func TestScanIdent(t *testing.T) {
f := func(s, resultExpected string) {
t.Helper()
result := scanIdent(s)
if result != resultExpected {
t.Fatalf("unexpected result for scanIdent(%q): got %q; want %q", s, result, resultExpected)
}
}
f("a", "a")
f("foo.bar:baz_123", "foo.bar:baz_123")
f("a+b", "a")
f("foo()", "foo")
f(`a\-b+c`, `a\-b`)
f(`a\ b\\\ c\`, `a\ b\\\ c\`)
}
func TestLexerNextPrev(t *testing.T) {
var lex lexer
lex.Init("foo bar baz")

View File

@@ -6,7 +6,6 @@ import (
"strings"
"sync"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/storage"
)
@@ -25,6 +24,7 @@ func getDefaultWithArgExprs() []*withArgExpr {
`median_over_time(m) = quantile_over_time(0.5, m)`,
`range_median(q) = range_quantile(0.5, q)`,
`alias(q, name) = label_set(q, "__name__", name)`,
})
})
return defaultWithArgExprs
@@ -744,7 +744,7 @@ func expandWithExpr(was []*withArgExpr, e expr) (expr, error) {
if !t.HasNonEmptyMetricGroup() {
return t, nil
}
k := bytesutil.ToUnsafeString(t.TagFilters[0].Value)
k := string(appendEscapedIdent(nil, t.TagFilters[0].Value))
wa := getWithArgExpr(was, k)
if wa == nil {
return t, nil
@@ -1074,9 +1074,6 @@ func (p *parser) parseTagFilterExpr() (*tagFilterExpr, error) {
}
var tfe tagFilterExpr
tfe.Key = p.lex.Token
if tfe.Key == "__name__" {
tfe.Key = ""
}
if err := p.lex.Next(); err != nil {
return nil, err
}
@@ -1125,8 +1122,16 @@ func (tfe *tagFilterExpr) toTagFilter() (*storage.TagFilter, error) {
}
var tf storage.TagFilter
tf.Key = []byte(tfe.Key)
tf.Value = []byte(tfe.Value.S)
tf.Key = []byte(unescapeIdent(tfe.Key))
if len(tfe.Key) == 0 {
tf.Value = []byte(unescapeIdent(tfe.Value.S))
} else {
tf.Value = []byte(tfe.Value.S)
}
if string(tf.Key) == "__name__" {
// This is required for storage.Search
tf.Key = nil
}
tf.IsRegexp = tfe.IsRegexp
tf.IsNegative = tfe.IsNegative
if !tf.IsRegexp {
@@ -1507,7 +1512,7 @@ func (wa *withArgExpr) AppendString(dst []byte) []byte {
}
type rollupExpr struct {
// The expression for the rollup. Usually it is metricExpr, but may be arbitary expr
// The expression for the rollup. Usually it is metricExpr, but may be arbitrary expr
// if subquery is used. https://prometheus.io/blog/2019/01/28/subquery-support/
Expr expr
@@ -1585,7 +1590,7 @@ func (me *metricExpr) AppendString(dst []byte) []byte {
if len(tfs) > 0 {
tf := &tfs[0]
if len(tf.Key) == 0 && !tf.IsNegative && !tf.IsRegexp {
dst = append(dst, tf.Value...)
dst = appendEscapedIdent(dst, tf.Value)
tfs = tfs[1:]
}
}
@@ -1627,7 +1632,7 @@ func appendStringTagFilter(dst []byte, tf *storage.TagFilter) []byte {
if len(tf.Key) == 0 {
dst = append(dst, "__name__"...)
} else {
dst = append(dst, tf.Key...)
dst = appendEscapedIdent(dst, tf.Key)
}
var op string
if tf.IsNegative {

View File

@@ -118,6 +118,13 @@ func TestParsePromQLSuccess(t *testing.T) {
same("with")
same("WITH")
same("With")
// identifiers with with escape chars
same(`foo\ bar`)
same(`foo\-bar\{{baz\+bar="aa"}`)
another(`\x2E\x2ef\oo{b\xEF\ar="aa"}`, `\x2e.foo{b\xefar="aa"}`)
// Duplicate filters
same(`foo{__name__="bar"}`)
same(`foo{a="b", a="c", __name__="aaa", b="d"}`)
// Metric filters ending with comma
another(`m{foo="bar",}`, `m{foo="bar"}`)
// String concat in tag value
@@ -251,6 +258,8 @@ func TestParsePromQLSuccess(t *testing.T) {
same(`rate(rate(m[5m]))`)
same(`rate(rate(m[5m])[1h:])`)
same(`rate(rate(m[5m])[1h:3s])`)
// funcName with escape chars
same(`foo\(ba\-r()`)
// aggrFuncExpr
same(`sum(http_server_request) by ()`)
@@ -295,10 +304,14 @@ func TestParsePromQLSuccess(t *testing.T) {
another(`with (ct={job="test", i="bar"}) ct + {ct, x="d"} + foo{ct, ct} + ctx(1)`,
`(({job="test", i="bar"} + {job="test", i="bar", x="d"}) + foo{job="test", i="bar"}) + ctx(1)`)
another(`with (foo = bar) {__name__=~"foo"}`, `{__name__=~"foo"}`)
another(`with (foo = bar) {__name__="foo"}`, `bar`)
another(`with (foo = bar) foo{__name__="foo"}`, `bar`)
another(`with (foo = bar) {__name__="foo", x="y"}`, `bar{x="y"}`)
another(`with (foo(bar) = {__name__!="bar"}) foo(x)`, `{__name__!="bar"}`)
another(`with (foo(bar) = {__name__="bar"}) foo(x)`, `x`)
another(`with (foo(bar) = bar{__name__="bar"}) foo(x)`, `x`)
another(`with (foo\-bar(baz) = baz + baz) foo\-bar((x,y))`, `(x, y) + (x, y)`)
another(`with (foo\-bar(baz) = baz + baz) foo\-bar(x*y)`, `(x * y) + (x * y)`)
another(`with (foo\-bar(baz) = baz + baz) foo\-bar(x\*y)`, `x\*y + x\*y`)
another(`with (foo\-bar(b\ az) = b\ az + b\ az) foo\-bar(x\*y)`, `x\*y + x\*y`)
// override ttf to something new.
another(`with (ttf = a) ttf + b`, `a + b`)
// override ttf to ru

View File

@@ -1,7 +1,6 @@
package promql
import (
"fmt"
"regexp"
"sync"
"sync/atomic"
@@ -10,12 +9,16 @@ import (
)
func compileRegexpAnchored(re string) (*regexp.Regexp, error) {
reAnchored := "^(?:" + re + ")$"
return compileRegexp(reAnchored)
}
func compileRegexp(re string) (*regexp.Regexp, error) {
rcv := regexpCacheV.Get(re)
if rcv != nil {
return rcv.r, rcv.err
}
regexAnchored := fmt.Sprintf("^(?:%s)$", re)
r, err := regexp.Compile(regexAnchored)
r, err := regexp.Compile(re)
rcv = &regexpCacheValue{
r: r,
err: err,

View File

@@ -2,6 +2,7 @@ package promql
import (
"crypto/rand"
"flag"
"fmt"
"runtime"
"sync"
@@ -15,6 +16,8 @@ import (
"github.com/VictoriaMetrics/metrics"
)
var disableCache = flag.Bool("search.disableCache", false, "Whether to disable response caching. This may be useful during data backfilling")
var rollupResultCacheV = &rollupResultCache{
fastcache.New(1024 * 1024), // This is a cache for testing.
}
@@ -47,6 +50,10 @@ func InitRollupResultCache(cachePath string) {
} else {
c = fastcache.New(getRollupResultCacheSize())
}
if *disableCache {
c.Reset()
}
stats := &fastcache.Stats{}
var statsLock sync.Mutex
var statsLastUpdate time.Time
@@ -119,7 +126,7 @@ func ResetRollupResultCache() {
}
func (rrc *rollupResultCache) Get(funcName string, ec *EvalConfig, me *metricExpr, window int64) (tss []*timeseries, newStart int64) {
if !ec.mayCache() {
if *disableCache || !ec.mayCache() {
return nil, ec.Start
}
@@ -190,7 +197,7 @@ func (rrc *rollupResultCache) Get(funcName string, ec *EvalConfig, me *metricExp
}
func (rrc *rollupResultCache) Put(funcName string, ec *EvalConfig, me *metricExpr, window int64, tss []*timeseries) {
if len(tss) == 0 || !ec.mayCache() {
if *disableCache || len(tss) == 0 || !ec.mayCache() {
return
}

View File

@@ -39,7 +39,7 @@ func TestRollupResultCache(t *testing.T) {
t.Run("start-overlap", func(t *testing.T) {
ResetRollupResultCache()
tss := []*timeseries{
&timeseries{
{
Timestamps: []int64{800, 1000, 1200},
Values: []float64{0, 1, 2},
},
@@ -50,7 +50,7 @@ func TestRollupResultCache(t *testing.T) {
t.Fatalf("unexpected newStart; got %d; want %d", newStart, 1400)
}
tssExpected := []*timeseries{
&timeseries{
{
Timestamps: []int64{1000, 1200},
Values: []float64{1, 2},
},
@@ -62,7 +62,7 @@ func TestRollupResultCache(t *testing.T) {
t.Run("end-overlap", func(t *testing.T) {
ResetRollupResultCache()
tss := []*timeseries{
&timeseries{
{
Timestamps: []int64{1800, 2000, 2200, 2400},
Values: []float64{333, 0, 1, 2},
},
@@ -81,7 +81,7 @@ func TestRollupResultCache(t *testing.T) {
t.Run("full-cover", func(t *testing.T) {
ResetRollupResultCache()
tss := []*timeseries{
&timeseries{
{
Timestamps: []int64{1200, 1400, 1600},
Values: []float64{0, 1, 2},
},
@@ -100,7 +100,7 @@ func TestRollupResultCache(t *testing.T) {
t.Run("before-start", func(t *testing.T) {
ResetRollupResultCache()
tss := []*timeseries{
&timeseries{
{
Timestamps: []int64{200, 400, 600},
Values: []float64{0, 1, 2},
},
@@ -119,7 +119,7 @@ func TestRollupResultCache(t *testing.T) {
t.Run("after-end", func(t *testing.T) {
ResetRollupResultCache()
tss := []*timeseries{
&timeseries{
{
Timestamps: []int64{2200, 2400, 2600},
Values: []float64{0, 1, 2},
},
@@ -138,7 +138,7 @@ func TestRollupResultCache(t *testing.T) {
t.Run("bigger-than-start-end", func(t *testing.T) {
ResetRollupResultCache()
tss := []*timeseries{
&timeseries{
{
Timestamps: []int64{800, 1000, 1200, 1400, 1600, 1800, 2000, 2200},
Values: []float64{0, 1, 2, 3, 4, 5, 6, 7},
},
@@ -149,7 +149,7 @@ func TestRollupResultCache(t *testing.T) {
t.Fatalf("unexpected newStart; got %d; want %d", newStart, 2200)
}
tssExpected := []*timeseries{
&timeseries{
{
Timestamps: []int64{1000, 1200, 1400, 1600, 1800, 2000},
Values: []float64{1, 2, 3, 4, 5, 6},
},
@@ -161,7 +161,7 @@ func TestRollupResultCache(t *testing.T) {
t.Run("start-end-match", func(t *testing.T) {
ResetRollupResultCache()
tss := []*timeseries{
&timeseries{
{
Timestamps: []int64{1000, 1200, 1400, 1600, 1800, 2000},
Values: []float64{1, 2, 3, 4, 5, 6},
},
@@ -172,7 +172,7 @@ func TestRollupResultCache(t *testing.T) {
t.Fatalf("unexpected newStart; got %d; want %d", newStart, 2200)
}
tssExpected := []*timeseries{
&timeseries{
{
Timestamps: []int64{1000, 1200, 1400, 1600, 1800, 2000},
Values: []float64{1, 2, 3, 4, 5, 6},
},
@@ -203,19 +203,19 @@ func TestRollupResultCache(t *testing.T) {
t.Run("multi-timeseries", func(t *testing.T) {
ResetRollupResultCache()
tss1 := []*timeseries{
&timeseries{
{
Timestamps: []int64{800, 1000, 1200},
Values: []float64{0, 1, 2},
},
}
tss2 := []*timeseries{
&timeseries{
{
Timestamps: []int64{1800, 2000, 2200, 2400},
Values: []float64{333, 0, 1, 2},
},
}
tss3 := []*timeseries{
&timeseries{
{
Timestamps: []int64{1200, 1400, 1600},
Values: []float64{0, 1, 2},
},
@@ -228,7 +228,7 @@ func TestRollupResultCache(t *testing.T) {
t.Fatalf("unexpected newStart; got %d; want %d", newStart, 1400)
}
tssExpected := []*timeseries{
&timeseries{
{
Timestamps: []int64{1000, 1200},
Values: []float64{1, 2},
},
@@ -249,14 +249,14 @@ func TestMergeTimeseries(t *testing.T) {
t.Run("bStart=ec.Start", func(t *testing.T) {
a := []*timeseries{}
b := []*timeseries{
&timeseries{
{
Timestamps: []int64{1000, 1200, 1400, 1600, 1800, 2000},
Values: []float64{1, 2, 3, 4, 5, 6},
},
}
tss := mergeTimeseries(a, b, 1000, ec)
tssExpected := []*timeseries{
&timeseries{
{
Timestamps: []int64{1000, 1200, 1400, 1600, 1800, 2000},
Values: []float64{1, 2, 3, 4, 5, 6},
},
@@ -266,14 +266,14 @@ func TestMergeTimeseries(t *testing.T) {
t.Run("a-empty", func(t *testing.T) {
a := []*timeseries{}
b := []*timeseries{
&timeseries{
{
Timestamps: []int64{1400, 1600, 1800, 2000},
Values: []float64{3, 4, 5, 6},
},
}
tss := mergeTimeseries(a, b, bStart, ec)
tssExpected := []*timeseries{
&timeseries{
{
Timestamps: []int64{1000, 1200, 1400, 1600, 1800, 2000},
Values: []float64{nan, nan, 3, 4, 5, 6},
},
@@ -282,7 +282,7 @@ func TestMergeTimeseries(t *testing.T) {
})
t.Run("b-empty", func(t *testing.T) {
a := []*timeseries{
&timeseries{
{
Timestamps: []int64{1000, 1200},
Values: []float64{2, 1},
},
@@ -290,7 +290,7 @@ func TestMergeTimeseries(t *testing.T) {
b := []*timeseries{}
tss := mergeTimeseries(a, b, bStart, ec)
tssExpected := []*timeseries{
&timeseries{
{
Timestamps: []int64{1000, 1200, 1400, 1600, 1800, 2000},
Values: []float64{2, 1, nan, nan, nan, nan},
},
@@ -299,20 +299,20 @@ func TestMergeTimeseries(t *testing.T) {
})
t.Run("non-empty", func(t *testing.T) {
a := []*timeseries{
&timeseries{
{
Timestamps: []int64{1000, 1200},
Values: []float64{2, 1},
},
}
b := []*timeseries{
&timeseries{
{
Timestamps: []int64{1400, 1600, 1800, 2000},
Values: []float64{3, 4, 5, 6},
},
}
tss := mergeTimeseries(a, b, bStart, ec)
tssExpected := []*timeseries{
&timeseries{
{
Timestamps: []int64{1000, 1200, 1400, 1600, 1800, 2000},
Values: []float64{2, 1, 3, 4, 5, 6},
},
@@ -321,14 +321,14 @@ func TestMergeTimeseries(t *testing.T) {
})
t.Run("non-empty-distinct-metric-names", func(t *testing.T) {
a := []*timeseries{
&timeseries{
{
Timestamps: []int64{1000, 1200},
Values: []float64{2, 1},
},
}
a[0].MetricName.MetricGroup = []byte("bar")
b := []*timeseries{
&timeseries{
{
Timestamps: []int64{1400, 1600, 1800, 2000},
Values: []float64{3, 4, 5, 6},
},
@@ -336,14 +336,14 @@ func TestMergeTimeseries(t *testing.T) {
b[0].MetricName.MetricGroup = []byte("foo")
tss := mergeTimeseries(a, b, bStart, ec)
tssExpected := []*timeseries{
&timeseries{
{
MetricName: storage.MetricName{
MetricGroup: []byte("foo"),
},
Timestamps: []int64{1000, 1200, 1400, 1600, 1800, 2000},
Values: []float64{nan, nan, 3, 4, 5, 6},
},
&timeseries{
{
MetricName: storage.MetricName{
MetricGroup: []byte("bar"),
},

View File

@@ -38,11 +38,13 @@ func (ts *timeseries) String() string {
return fmt.Sprintf("MetricName=%s, Values=%g, Timestamps=%d", &ts.MetricName, ts.Values, ts.Timestamps)
}
func (ts *timeseries) CopyFrom(src *timeseries) {
func (ts *timeseries) CopyFromShallowTimestamps(src *timeseries) {
ts.Reset()
ts.MetricName.CopyFrom(&src.MetricName)
ts.Values = append(ts.Values[:0], src.Values...)
ts.Timestamps = append(ts.Timestamps[:0], src.Timestamps...)
ts.Timestamps = src.Timestamps
ts.denyReuse = true
}
func (ts *timeseries) CopyFromMetricNames(src *timeseries) {

View File

@@ -4,6 +4,7 @@ import (
"fmt"
"math"
"math/rand"
"regexp"
"sort"
"strconv"
"strings"
@@ -61,6 +62,7 @@ var transformFuncs = map[string]transformFunc{
"label_keep": transformLabelKeep,
"label_copy": transformLabelCopy,
"label_move": transformLabelMove,
"label_transform": transformLabelTransform,
"union": transformUnion,
"": transformUnion, // empty func is a synonim to union
"keep_last_value": transformKeepLastValue,
@@ -294,14 +296,12 @@ func transformHistogramQuantile(tfa *transformFuncArg) ([]*timeseries, error) {
if err != nil {
continue
}
var dst timeseries
dst.CopyFrom(ts)
dst.MetricName.ResetMetricGroup()
dst.MetricName.RemoveTag("le")
bb.B = marshalMetricTagsSorted(bb.B[:0], &dst.MetricName)
ts.MetricName.ResetMetricGroup()
ts.MetricName.RemoveTag("le")
bb.B = marshalMetricTagsSorted(bb.B[:0], &ts.MetricName)
m[string(bb.B)] = append(m[string(bb.B)], x{
le: le,
ts: &dst,
ts: ts,
})
}
bbPool.Put(bb)
@@ -641,9 +641,7 @@ func transformUnion(tfa *transformFuncArg) ([]*timeseries, error) {
continue
}
m[string(bb.B)] = true
var dst timeseries
dst.CopyFrom(ts)
rvs = append(rvs, &dst)
rvs = append(rvs, ts)
}
}
bbPool.Put(bb)
@@ -816,6 +814,31 @@ func transformLabelJoin(tfa *transformFuncArg) ([]*timeseries, error) {
return rvs, nil
}
func transformLabelTransform(tfa *transformFuncArg) ([]*timeseries, error) {
args := tfa.args
if err := expectTransformArgsNum(args, 4); err != nil {
return nil, err
}
label, err := getString(args[1], 1)
if err != nil {
return nil, err
}
regex, err := getString(args[2], 2)
if err != nil {
return nil, err
}
replacement, err := getString(args[3], 3)
if err != nil {
return nil, err
}
r, err := compileRegexp(regex)
if err != nil {
return nil, fmt.Errorf(`cannot compile regex %q: %s`, regex, err)
}
return labelReplace(args[0], label, r, label, replacement)
}
func transformLabelReplace(tfa *transformFuncArg) ([]*timeseries, error) {
args := tfa.args
if err := expectTransformArgsNum(args, 5); err != nil {
@@ -842,11 +865,12 @@ func transformLabelReplace(tfa *transformFuncArg) ([]*timeseries, error) {
if err != nil {
return nil, fmt.Errorf(`cannot compile regex %q: %s`, regex, err)
}
return labelReplace(args[0], srcLabel, r, dstLabel, replacement)
}
func labelReplace(tss []*timeseries, srcLabel string, r *regexp.Regexp, dstLabel, replacement string) ([]*timeseries, error) {
replacementBytes := []byte(replacement)
rvs := args[0]
for _, ts := range rvs {
for _, ts := range tss {
mn := &ts.MetricName
dstValue := getDstValue(mn, dstLabel)
srcValue := mn.GetTagValue(srcLabel)
@@ -856,7 +880,7 @@ func transformLabelReplace(tfa *transformFuncArg) ([]*timeseries, error) {
mn.RemoveTag(dstLabel)
}
}
return rvs, nil
return tss, nil
}
func transformLn(v float64) float64 {

View File

@@ -96,6 +96,14 @@ func SearchTagValues(tagKey []byte, maxTagValues int) ([]string, error) {
return values, err
}
// SearchTagEntries searches for tag entries.
func SearchTagEntries(maxTagKeys, maxTagValues int) ([]storage.TagEntry, error) {
WG.Add(1)
tagEntries, err := Storage.SearchTagEntries(maxTagKeys, maxTagValues)
WG.Done()
return tagEntries, err
}
// GetSeriesCount returns the number of time series in the storage.
func GetSeriesCount() (uint64, error) {
WG.Add(1)
@@ -285,6 +293,18 @@ func registerStorageMetrics(strg *storage.Storage) {
metrics.NewGauge(`vm_missing_tsids_for_metric_id_total`, func() float64 {
return float64(idbm().MissingTSIDsForMetricID)
})
metrics.NewGauge(`vm_recent_hour_metric_ids_search_calls_total`, func() float64 {
return float64(idbm().RecentHourMetricIDsSearchCalls)
})
metrics.NewGauge(`vm_recent_hour_metric_ids_search_hits_total`, func() float64 {
return float64(idbm().RecentHourMetricIDsSearchHits)
})
metrics.NewGauge(`vm_date_metric_ids_search_calls_total`, func() float64 {
return float64(idbm().DateMetricIDsSearchCalls)
})
metrics.NewGauge(`vm_date_metric_ids_search_hits_total`, func() float64 {
return float64(idbm().DateMetricIDsSearchHits)
})
metrics.NewGauge(`vm_assisted_merges_total{type="storage/small"}`, func() float64 {
return float64(tm().SmallAssistedMerges)
@@ -357,6 +377,9 @@ func registerStorageMetrics(strg *storage.Storage) {
metrics.NewGauge(`vm_cache_entries{type="indexdb/tagFilters"}`, func() float64 {
return float64(idbm().TagCacheSize)
})
metrics.NewGauge(`vm_cache_entries{type="indexdb/uselessTagFilters"}`, func() float64 {
return float64(idbm().UselessTagFiltersCacheSize)
})
metrics.NewGauge(`vm_cache_entries{type="storage/regexps"}`, func() float64 {
return float64(storage.RegexpCacheSize())
})
@@ -376,6 +399,9 @@ func registerStorageMetrics(strg *storage.Storage) {
metrics.NewGauge(`vm_cache_size_bytes{type="indexdb/tagFilters"}`, func() float64 {
return float64(idbm().TagCacheBytesSize)
})
metrics.NewGauge(`vm_cache_size_bytes{type="indexdb/uselessTagFilters"}`, func() float64 {
return float64(idbm().UselessTagFiltersCacheBytesSize)
})
metrics.NewGauge(`vm_cache_requests_total{type="storage/tsid"}`, func() float64 {
return float64(m().TSIDCacheRequests)
@@ -404,6 +430,9 @@ func registerStorageMetrics(strg *storage.Storage) {
metrics.NewGauge(`vm_cache_requests_total{type="indexdb/tagFilters"}`, func() float64 {
return float64(idbm().TagCacheRequests)
})
metrics.NewGauge(`vm_cache_requests_total{type="indexdb/uselessTagFilters"}`, func() float64 {
return float64(idbm().UselessTagFiltersCacheRequests)
})
metrics.NewGauge(`vm_cache_requests_total{type="storage/regexps"}`, func() float64 {
return float64(storage.RegexpCacheRequests())
})
@@ -435,6 +464,9 @@ func registerStorageMetrics(strg *storage.Storage) {
metrics.NewGauge(`vm_cache_misses_total{type="indexdb/tagFilters"}`, func() float64 {
return float64(idbm().TagCacheMisses)
})
metrics.NewGauge(`vm_cache_misses_total{type="indexdb/uselessTagFilters"}`, func() float64 {
return float64(idbm().UselessTagFiltersCacheMisses)
})
metrics.NewGauge(`vm_cache_misses_total{type="storage/regexps"}`, func() float64 {
return float64(storage.RegexpCacheMisses())
})

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
DOCKER_NAMESPACE := valyala
DOCKER_NAMESPACE := victoriametrics
BUILDER_IMAGE := local/builder:go1.12.5
CERTS_IMAGE := local/certs:1.0.2
@@ -18,6 +18,7 @@ app-via-docker: package-certs package-builder
-w /VictoriaMetrics \
--mount type=bind,src="$(shell pwd)/gocache-for-docker",dst=/gocache \
--env GOCACHE=/gocache \
--env GO111MODULE=on \
$(BUILDER_IMAGE) \
go build $(RACE) -mod=vendor -ldflags "-s -w -extldflags '-static' $(GO_BUILDINFO)" -tags 'netgo osusergo' -o bin/$(APP_NAME)-prod $(PKG_PREFIX)/app/$(APP_NAME)

View File

@@ -0,0 +1,33 @@
### Folder contains basic images and tools for building and running Victoria Metrics in docker
#### Docker compose
To spin-up setup of VictoriaMetrics, Prometheus and Grafana run following command:
`docker-compose up`
##### VictoriaMetrics
VictoriaMetrics opens following ports:
* `--graphiteListenAddr=:2003`
* `--opentsdbListenAddr=:4242`
* `--httpListenAddr=:8428`
##### Prometheus
To access service open following [link](http://localhost:9090).
Prometheus is already configured to use VictoriaMetrics as remote storage.
##### Grafana
To access service open following [link](http://localhost:3000).
Default creds:
* login - `admin`
* password - `admin`
Grafana is provisioned by default with following entities:
* VictoriaMetrics datasource
* Prometheus datasource
* VictoriaMetrics overview dashboard

View File

@@ -1 +1,2 @@
FROM golang:1.12.5
STOPSIGNAL SIGINT

View File

@@ -0,0 +1,61 @@
version: '3.5'
services:
prometheus:
container_name: prometheus
image: prom/prometheus:v2.10.0
depends_on:
- "victoriametrics"
ports:
- 9090:9090
volumes:
- promdata:/prometheus
- ./prometheus.yml:/etc/prometheus/prometheus.yml
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
networks:
- vm_net
restart: always
victoriametrics:
container_name: victoriametrics
image: victoriametrics/victoria-metrics
ports:
- 8428:8428
- 2003:2003
- 4242:4242
volumes:
- vmdata:/storage
command:
- '--storageDataPath=/storage'
- '--graphiteListenAddr=:2003'
- '--opentsdbListenAddr=:4242'
- '--httpListenAddr=:8428'
networks:
- vm_net
restart: always
grafana:
container_name: grafana
image: grafana/grafana:6.2.1
entrypoint: >
/bin/sh -c "
cd /var/lib/grafana &&
mkdir -p dashboards &&
sed 's/$${DS_PROMETHEUS}/Prometheus/g' vm.json > dashboards/vm.json &&
/run.sh"
depends_on:
- "victoriametrics"
ports:
- 3000:3000
volumes:
- grafanadata:/var/lib/grafana
- ./provisioning/:/etc/grafana/provisioning/
- ./../../dashboards/victoriametrics.json:/var/lib/grafana/vm.json
networks:
- vm_net
restart: always
volumes:
promdata: {}
vmdata: {}
grafanadata: {}
networks:
vm_net:

View File

@@ -0,0 +1,16 @@
global:
scrape_interval: 10s
evaluation_interval: 10s
remote_write:
- url: "http://victoriametrics:8428/api/v1/write"
queue_config:
max_samples_per_send: 10000
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['prometheus:9090']
- job_name: 'victoriametrics'
static_configs:
- targets: ['victoriametrics:8428']

View File

@@ -0,0 +1,9 @@
apiVersion: 1
providers:
- name: Prometheus
orgId: 1
folder: ''
type: file
options:
path: /var/lib/grafana/dashboards

View File

@@ -0,0 +1,14 @@
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: false
- name: VictoriaMetrics
type: prometheus
access: proxy
url: http://victoriametrics:8428
isDefault: true

6
go.mod
View File

@@ -1,8 +1,8 @@
module github.com/VictoriaMetrics/VictoriaMetrics
require (
github.com/VictoriaMetrics/fastcache v1.5.0
github.com/VictoriaMetrics/metrics v1.4.0
github.com/VictoriaMetrics/fastcache v1.5.1
github.com/VictoriaMetrics/metrics v1.5.0
github.com/cespare/xxhash/v2 v2.0.1-0.20190104013014-3767db7a7e18
github.com/golang/snappy v0.0.1
github.com/spaolacci/murmur3 v1.1.0 // indirect
@@ -10,7 +10,7 @@ require (
github.com/valyala/gozstd v1.5.0
github.com/valyala/histogram v1.0.1
github.com/valyala/quicktemplate v1.1.1
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2
)
go 1.12

12
go.sum
View File

@@ -1,10 +1,10 @@
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI=
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/VictoriaMetrics/fastcache v1.5.0 h1:z8t2QV/CDXWVJ9vy9yRtGGDoOvk9W2aXQBijbLk0KCc=
github.com/VictoriaMetrics/fastcache v1.5.0/go.mod h1:+jv9Ckb+za/P1ZRg/sulP5Ni1v49daAVERr0H3CuscE=
github.com/VictoriaMetrics/metrics v1.4.0 h1:3+XdciC4E8sywx+0PStXhtIdWxXP2bdJ06Whw0mViQE=
github.com/VictoriaMetrics/metrics v1.4.0/go.mod h1:QZAL5yLaXvhSPeib0ahluGo9VK0HXDZHovKaKlpuWvs=
github.com/VictoriaMetrics/fastcache v1.5.1 h1:qHgHjyoNFV7jgucU8QZUuU4gcdhfs8QW1kw68OD2Lag=
github.com/VictoriaMetrics/fastcache v1.5.1/go.mod h1:+jv9Ckb+za/P1ZRg/sulP5Ni1v49daAVERr0H3CuscE=
github.com/VictoriaMetrics/metrics v1.5.0 h1:WvQqPn+z9pR1U7J58CgaGiWrN8phNGSpr2xUSxJnfpE=
github.com/VictoriaMetrics/metrics v1.5.0/go.mod h1:QZAL5yLaXvhSPeib0ahluGo9VK0HXDZHovKaKlpuWvs=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
@@ -44,5 +44,5 @@ github.com/valyala/quicktemplate v1.1.1 h1:C58y/wN0FMTi2PR0n3onltemfFabany53j7M6
github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82 h1:vsphBvatvfbhlb4PO1BYSr9dzugGxJ/SQHoNufZJq1w=
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2 h1:T5DasATyLQfmbTpfEXx/IOL9vfjzW6up+ZDkmHvIf2s=
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@@ -44,7 +44,7 @@ func (bb *ByteBuffer) ReadAt(p []byte, offset int64) {
logger.Panicf("BUG: too big offset=%d; cannot exceed len(bb.B)=%d", offset, len(bb.B))
}
if n := copy(p, bb.B[offset:]); n < len(p) {
logger.Panicf("BUG: EOF occured after reading %d bytes out of %d bytes at offset %d", n, len(p), offset)
logger.Panicf("BUG: EOF occurred after reading %d bytes out of %d bytes at offset %d", n, len(p), offset)
}
}

View File

@@ -186,6 +186,7 @@ func maxUpExponent(v int64) int16 {
v = -v
}
if v < 0 {
// Handle corner case for v=-1<<63
return 0
}

View File

@@ -1,27 +1,34 @@
package encoding
import (
"github.com/VictoriaMetrics/metrics"
"github.com/valyala/gozstd"
)
// CompressZSTD compresses src, appends the result to dst and returns
// the appended dst.
//
// src must be non-empty.
func CompressZSTD(dst, src []byte) []byte {
return gozstd.CompressLevel(dst, src, 5)
}
// CompressZSTDLevel appends compressed src to dst and returns
// the appended dst.
//
// The given compressLevel is used for the compression.
func CompressZSTDLevel(dst, src []byte, compressLevel int) []byte {
return gozstd.CompressLevel(dst, src, compressLevel)
compressCalls.Inc()
originalBytes.Add(len(src))
dstLen := len(dst)
dst = gozstd.CompressLevel(dst, src, compressLevel)
compressedBytes.Add(len(dst) - dstLen)
return dst
}
// DecompressZSTD decompresses src, appends the result to dst and returns
// the appended dst.
func DecompressZSTD(dst, src []byte) ([]byte, error) {
decompressCalls.Inc()
return gozstd.Decompress(dst, src)
}
var (
compressCalls = metrics.NewCounter(`vm_zstd_block_compress_calls_total`)
decompressCalls = metrics.NewCounter(`vm_zstd_block_decompress_calls_total`)
originalBytes = metrics.NewCounter(`vm_zstd_block_original_bytes_total`)
compressedBytes = metrics.NewCounter(`vm_zstd_block_compressed_bytes_total`)
)

View File

@@ -17,7 +17,7 @@ func TestCompressDecompressZSTD(t *testing.T) {
}
func testCompressDecompressZSTD(t *testing.T, b []byte) {
bc := CompressZSTD(nil, b)
bc := CompressZSTDLevel(nil, b, 5)
bNew, err := DecompressZSTD(nil, bc)
if err != nil {
t.Fatalf("unexpected error when decompressing b=%x from bc=%x: %s", b, bc, err)
@@ -27,7 +27,7 @@ func testCompressDecompressZSTD(t *testing.T, b []byte) {
}
prefix := []byte{1, 2, 33}
bcNew := CompressZSTD(prefix, b)
bcNew := CompressZSTDLevel(prefix, b, 5)
if string(bcNew[:len(prefix)]) != string(prefix) {
t.Fatalf("invalid prefix for b=%x; got\n%x; expecting\n%x", b, bcNew[:len(prefix)], prefix)
}

View File

@@ -117,7 +117,7 @@ func marshalInt64Array(dst []byte, a []int64, precisionBits uint8) (result []byt
bb := bbPool.Get()
if isGauge(a) {
// Guage values are better compressed with delta encoding.
// Gauge values are better compressed with delta encoding.
mt = MarshalTypeZSTDNearestDelta
pb := precisionBits
if pb < 6 {

View File

@@ -5,6 +5,8 @@ import (
"io"
"os"
"path/filepath"
"strings"
"time"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/filestream"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
@@ -70,8 +72,8 @@ var (
readersCount = metrics.NewCounter(`vm_fs_readers`)
)
// SyncPath syncs contents of the given path.
func SyncPath(path string) {
// MustSyncPath syncs contents of the given path.
func MustSyncPath(path string) {
d, err := os.Open(path)
if err != nil {
logger.Panicf("FATAL: cannot open %q: %s", path, err)
@@ -111,8 +113,8 @@ func WriteFile(path string, data []byte) error {
if err != nil {
return fmt.Errorf("cannot obtain absolute path to %q: %s", path, err)
}
parentDirPath, _ := filepath.Split(absPath)
SyncPath(parentDirPath)
parentDirPath := filepath.Dir(absPath)
MustSyncPath(parentDirPath)
return nil
}
@@ -122,7 +124,7 @@ func MkdirAllIfNotExist(path string) error {
if IsPathExist(path) {
return nil
}
return os.MkdirAll(path, 0755)
return mkdirSync(path)
}
// MkdirAllFailIfExist creates the given path dir if it isn't exist.
@@ -132,7 +134,18 @@ func MkdirAllFailIfExist(path string) error {
if IsPathExist(path) {
return fmt.Errorf("the %q already exists", path)
}
return os.MkdirAll(path, 0755)
return mkdirSync(path)
}
func mkdirSync(path string) error {
if err := os.MkdirAll(path, 0755); err != nil {
return err
}
// Sync the parent directory, so the created directory becomes visible
// in the fs after power loss.
parentDirPath := filepath.Dir(path)
MustSyncPath(parentDirPath)
return nil
}
// RemoveDirContents removes all the contents of the given dir it it exists.
@@ -159,11 +172,9 @@ func RemoveDirContents(dir string) {
continue
}
fullPath := dir + "/" + name
if err := os.RemoveAll(fullPath); err != nil {
logger.Panicf("FATAL: cannot remove %q: %s", fullPath, err)
}
MustRemoveAll(fullPath)
}
SyncPath(dir)
MustSyncPath(dir)
}
// MustClose must close the given file f.
@@ -185,18 +196,79 @@ func IsPathExist(path string) bool {
return true
}
// MustRemoveAllSynced removes path with all the contents
// and syncs the parent directory, so it no longer contains the path.
func MustRemoveAllSynced(path string) {
if err := os.RemoveAll(path); err != nil {
func mustSyncParentDirIfExists(path string) {
parentDirPath := filepath.Dir(path)
if !IsPathExist(parentDirPath) {
return
}
MustSyncPath(parentDirPath)
}
// MustRemoveAll removes path with all the contents.
//
// It properly handles NFS issue https://github.com/VictoriaMetrics/VictoriaMetrics/issues/61 .
func MustRemoveAll(path string) {
err := os.RemoveAll(path)
if err == nil {
// Make sure the parent directory doesn't contain references
// to the current directory.
mustSyncParentDirIfExists(path)
return
}
if !isTemporaryNFSError(err) {
logger.Panicf("FATAL: cannot remove %q: %s", path, err)
}
SyncPath(filepath.Dir(path))
// NFS prevents from removing directories with open files.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/61 .
// Schedule for later directory removal.
select {
case removeDirCh <- path:
default:
logger.Panicf("FATAL: cannot schedule %s for removal, since the removal queue is full (%d entries)", path, cap(removeDirCh))
}
}
var removeDirCh = make(chan string, 1024)
func dirRemover() {
for path := range removeDirCh {
attempts := 0
for {
err := os.RemoveAll(path)
if err == nil {
break
}
if !isTemporaryNFSError(err) {
logger.Panicf("FATAL: cannot remove %q: %s", path, err)
}
// NFS prevents from removing directories with open files.
// Sleep for a while and try again in the hope open files will be closed.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/61 .
attempts++
if attempts > 10 {
logger.Panicf("FATAL: cannot remove %q in %d attempts: %s", path, attempts, err)
}
time.Sleep(100 * time.Millisecond)
}
// Make sure the parent directory doesn't contain references
// to the current directory.
mustSyncParentDirIfExists(path)
}
}
func isTemporaryNFSError(err error) bool {
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/61 for details.
errStr := err.Error()
return strings.Contains(errStr, "directory not empty") || strings.Contains(errStr, "device or resource busy")
}
func init() {
go dirRemover()
}
// HardLinkFiles makes hard links for all the files from srcDir in dstDir.
func HardLinkFiles(srcDir, dstDir string) error {
if err := os.MkdirAll(dstDir, 0755); err != nil {
if err := mkdirSync(dstDir); err != nil {
return fmt.Errorf("cannot create dstDir=%q: %s", dstDir, err)
}
@@ -227,7 +299,7 @@ func HardLinkFiles(srcDir, dstDir string) error {
}
}
SyncPath(dstDir)
MustSyncPath(dstDir)
return nil
}

View File

@@ -31,6 +31,8 @@ var (
httpAuthPassword = flag.String("httpAuth.password", "", "Password for HTTP Basic Auth. The authentication is disabled -httpAuth.username is empty")
metricsAuthKey = flag.String("metricsAuthKey", "", "Auth key for /metrics. It overrides httpAuth settings")
pprofAuthKey = flag.String("pprofAuthKey", "", "Auth key for /debug/pprof. It overrides httpAuth settings")
disableResponseCompression = flag.Bool("http.disableResponseCompression", false, "Disable compression of HTTP responses for saving CPU resources. By default compression is enabled to save network bandwidth")
)
var (
@@ -51,6 +53,8 @@ type RequestHandler func(w http.ResponseWriter, r *http.Request) bool
// By default all the responses are transparently compressed, since Google
// charges a lot for the egress traffic. The compression may be disabled
// by calling DisableResponseCompression before writing the first byte to w.
//
// The compression is also disabled if -http.disableResponseCompression flag is set.
func Serve(addr string, rh RequestHandler) {
scheme := "http"
if *tlsEnable {
@@ -224,6 +228,9 @@ func checkBasicAuth(w http.ResponseWriter, r *http.Request) bool {
}
func maybeGzipResponseWriter(w http.ResponseWriter, r *http.Request) http.ResponseWriter {
if *disableResponseCompression {
return w
}
ae := r.Header.Get("Accept-Encoding")
if ae == "" {
return w

View File

@@ -2,7 +2,6 @@ package mergeset
import (
"fmt"
"os"
"path/filepath"
"sync"
@@ -92,7 +91,7 @@ func (bsw *blockStreamWriter) InitFromFilePart(path string, nocache bool, compre
metaindexPath := path + "/metaindex.bin"
metaindexFile, err := filestream.Create(metaindexPath, false)
if err != nil {
_ = os.RemoveAll(path)
fs.MustRemoveAll(path)
return fmt.Errorf("cannot create metaindex file: %s", err)
}
@@ -100,7 +99,7 @@ func (bsw *blockStreamWriter) InitFromFilePart(path string, nocache bool, compre
indexFile, err := filestream.Create(indexPath, nocache)
if err != nil {
metaindexFile.MustClose()
_ = os.RemoveAll(path)
fs.MustRemoveAll(path)
return fmt.Errorf("cannot create index file: %s", err)
}
@@ -109,7 +108,7 @@ func (bsw *blockStreamWriter) InitFromFilePart(path string, nocache bool, compre
if err != nil {
metaindexFile.MustClose()
indexFile.MustClose()
_ = os.RemoveAll(path)
fs.MustRemoveAll(path)
return fmt.Errorf("cannot create items file: %s", err)
}
@@ -119,7 +118,7 @@ func (bsw *blockStreamWriter) InitFromFilePart(path string, nocache bool, compre
metaindexFile.MustClose()
indexFile.MustClose()
itemsFile.MustClose()
_ = os.RemoveAll(path)
fs.MustRemoveAll(path)
return fmt.Errorf("cannot create lens file: %s", err)
}
@@ -152,6 +151,12 @@ func (bsw *blockStreamWriter) MustClose() {
bsw.itemsWriter.MustClose()
bsw.lensWriter.MustClose()
// Sync bsw.path contents to make sure it doesn't disappear
// after system crash or power loss.
if bsw.path != "" {
fs.MustSyncPath(bsw.path)
}
bsw.reset()
}

View File

@@ -208,7 +208,7 @@ func (tb *Table) MustClose() {
logger.Infof("%d inmemory parts have been flushed to files in %s on %q", len(pws), time.Since(startTime), tb.path)
// Remove references to parts from the tb, so they may be eventually closed
// after all the seraches are done.
// after all the searches are done.
tb.partsLock.Lock()
parts := tb.parts
tb.parts = nil
@@ -846,22 +846,18 @@ func openParts(path string) ([]*partWrapper, error) {
}
txnDir := path + "/txn"
if err := os.RemoveAll(txnDir); err != nil {
return nil, fmt.Errorf("cannot remove %q: %s", txnDir, err)
}
fs.MustRemoveAll(txnDir)
if err := fs.MkdirAllFailIfExist(txnDir); err != nil {
return nil, fmt.Errorf("cannot create %q: %s", txnDir, err)
}
tmpDir := path + "/tmp"
if err := os.RemoveAll(tmpDir); err != nil {
return nil, fmt.Errorf("cannot remove %q: %s", tmpDir, err)
}
fs.MustRemoveAll(tmpDir)
if err := fs.MkdirAllFailIfExist(tmpDir); err != nil {
return nil, fmt.Errorf("cannot create %q: %s", tmpDir, err)
}
fs.SyncPath(path)
fs.MustSyncPath(path)
// Open parts.
fis, err := d.Readdir(-1)
@@ -965,9 +961,9 @@ func (tb *Table) CreateSnapshotAt(dstDir string) error {
}
}
fs.SyncPath(dstDir)
fs.MustSyncPath(dstDir)
parentDir := filepath.Dir(dstDir)
fs.SyncPath(parentDir)
fs.MustSyncPath(parentDir)
logger.Infof("created Table snapshot of %q at %q in %s", srcDir, dstDir, time.Since(startTime))
return nil
@@ -1033,9 +1029,7 @@ func runTransaction(txnLock *sync.RWMutex, pathPrefix, txnPath string) error {
if err != nil {
return fmt.Errorf("invalid path to remove: %s", err)
}
if err := os.RemoveAll(path); err != nil {
return fmt.Errorf("cannot remove %q: %s", path, err)
}
fs.MustRemoveAll(path)
}
// Move the new part to new directory.
@@ -1061,7 +1055,7 @@ func runTransaction(txnLock *sync.RWMutex, pathPrefix, txnPath string) error {
}
// Flush pathPrefix directory metadata to the underying storage.
fs.SyncPath(pathPrefix)
fs.MustSyncPath(pathPrefix)
// Remove the transaction file.
if err := os.Remove(txnPath); err != nil {

View File

@@ -33,6 +33,9 @@ func benchmarkTableSearch(b *testing.B, itemsCount int) {
// Force finishing pending merges
tb.MustClose()
tb, err = OpenTable(path)
if err != nil {
b.Fatalf("unexpected error when re-opening table %q: %s", path, err)
}
defer tb.MustClose()
keys := make([][]byte, len(items))

View File

@@ -6,7 +6,7 @@ import (
"syscall"
)
// WaitForSigterm waits fro either SIGTERM or SIGINT
// WaitForSigterm waits for either SIGTERM or SIGINT
//
// Returns the caught signal.
func WaitForSigterm() os.Signal {

View File

@@ -2,7 +2,6 @@ package storage
import (
"fmt"
"os"
"path/filepath"
"sync"
"sync/atomic"
@@ -85,7 +84,7 @@ func (bsw *blockStreamWriter) InitFromFilePart(path string, nocache bool, compre
timestampsPath := path + "/timestamps.bin"
timestampsFile, err := filestream.Create(timestampsPath, nocache)
if err != nil {
_ = os.RemoveAll(path)
fs.MustRemoveAll(path)
return fmt.Errorf("cannot create timestamps file: %s", err)
}
@@ -93,7 +92,7 @@ func (bsw *blockStreamWriter) InitFromFilePart(path string, nocache bool, compre
valuesFile, err := filestream.Create(valuesPath, nocache)
if err != nil {
timestampsFile.MustClose()
_ = os.RemoveAll(path)
fs.MustRemoveAll(path)
return fmt.Errorf("cannot create values file: %s", err)
}
@@ -102,7 +101,7 @@ func (bsw *blockStreamWriter) InitFromFilePart(path string, nocache bool, compre
if err != nil {
timestampsFile.MustClose()
valuesFile.MustClose()
_ = os.RemoveAll(path)
fs.MustRemoveAll(path)
return fmt.Errorf("cannot create index file: %s", err)
}
@@ -114,7 +113,7 @@ func (bsw *blockStreamWriter) InitFromFilePart(path string, nocache bool, compre
timestampsFile.MustClose()
valuesFile.MustClose()
indexFile.MustClose()
_ = os.RemoveAll(path)
fs.MustRemoveAll(path)
return fmt.Errorf("cannot create metaindex file: %s", err)
}
@@ -147,6 +146,12 @@ func (bsw *blockStreamWriter) MustClose() {
bsw.indexWriter.MustClose()
bsw.metaindexWriter.MustClose()
// Sync bsw.path contents to make sure it doesn't disappear
// after system crash or power loss.
if bsw.path != "" {
fs.MustSyncPath(bsw.path)
}
bsw.reset()
}

View File

@@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io"
"os"
"path/filepath"
"sort"
"sync"
@@ -15,6 +14,7 @@ import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/encoding"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fs"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/memory"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/mergeset"
@@ -60,6 +60,10 @@ type indexDB struct {
// Cache for fast MetricID -> MetricName lookup.
metricNameCache *fastcache.Cache
// Cache holding useless TagFilters entries, which have no tag filters
// matching low number of metrics.
uselessTagFiltersCache *fastcache.Cache
indexSearchPool sync.Pool
// An inmemory map[uint64]struct{} of deleted metricIDs.
@@ -71,15 +75,33 @@ type indexDB struct {
deletedMetricIDs atomic.Value
deletedMetricIDsUpdateLock sync.Mutex
// Global lists of metric ids for the current and the previous hours.
// They are used for fast lookups on small time ranges covering
// up to two last hours.
currHourMetricIDs *atomic.Value
prevHourMetricIDs *atomic.Value
// The number of missing MetricID -> TSID entries.
// High rate for this value means corrupted indexDB.
missingTSIDsForMetricID uint64
// The number of calls to search for metric ids for recent hours.
recentHourMetricIDsSearchCalls uint64
// The number of cache hits during search for metric ids in recent hours.
recentHourMetricIDsSearchHits uint64
// The number of searches for metric ids by days.
dateMetricIDsSearchCalls uint64
// The number of successful searches for metric ids by days.
dateMetricIDsSearchHits uint64
mustDrop uint64
}
// openIndexDB opens index db from the given path with the given caches.
func openIndexDB(path string, metricIDCache, metricNameCache *fastcache.Cache) (*indexDB, error) {
func openIndexDB(path string, metricIDCache, metricNameCache *fastcache.Cache, currHourMetricIDs, prevHourMetricIDs *atomic.Value) (*indexDB, error) {
tb, err := mergeset.OpenTable(path)
if err != nil {
return nil, fmt.Errorf("cannot open indexDB %q: %s", path, err)
@@ -99,6 +121,11 @@ func openIndexDB(path string, metricIDCache, metricNameCache *fastcache.Cache) (
tagCache: tagCache,
metricIDCache: metricIDCache,
metricNameCache: metricNameCache,
uselessTagFiltersCache: fastcache.New(mem / 128),
currHourMetricIDs: currHourMetricIDs,
prevHourMetricIDs: prevHourMetricIDs,
}
is := db.getIndexSearch()
@@ -119,12 +146,22 @@ type IndexDBMetrics struct {
TagCacheRequests uint64
TagCacheMisses uint64
UselessTagFiltersCacheSize uint64
UselessTagFiltersCacheBytesSize uint64
UselessTagFiltersCacheRequests uint64
UselessTagFiltersCacheMisses uint64
DeletedMetricsCount uint64
IndexDBRefCount uint64
MissingTSIDsForMetricID uint64
RecentHourMetricIDsSearchCalls uint64
RecentHourMetricIDsSearchHits uint64
DateMetricIDsSearchCalls uint64
DateMetricIDsSearchHits uint64
mergeset.TableMetrics
}
@@ -135,16 +172,29 @@ func (db *indexDB) scheduleToDrop() {
// UpdateMetrics updates m with metrics from the db.
func (db *indexDB) UpdateMetrics(m *IndexDBMetrics) {
var cs fastcache.Stats
cs.Reset()
db.tagCache.UpdateStats(&cs)
m.TagCacheSize += cs.EntriesCount
m.TagCacheBytesSize += cs.BytesSize
m.TagCacheRequests += cs.GetBigCalls
m.TagCacheMisses += cs.Misses
cs.Reset()
db.uselessTagFiltersCache.UpdateStats(&cs)
m.UselessTagFiltersCacheSize += cs.EntriesCount
m.UselessTagFiltersCacheBytesSize += cs.BytesSize
m.UselessTagFiltersCacheRequests += cs.GetBigCalls
m.UselessTagFiltersCacheMisses += cs.Misses
m.DeletedMetricsCount += uint64(len(db.getDeletedMetricIDs()))
m.IndexDBRefCount += atomic.LoadUint64(&db.refCount)
m.MissingTSIDsForMetricID += atomic.LoadUint64(&db.missingTSIDsForMetricID)
m.RecentHourMetricIDsSearchCalls += atomic.LoadUint64(&db.recentHourMetricIDsSearchCalls)
m.RecentHourMetricIDsSearchHits += atomic.LoadUint64(&db.recentHourMetricIDsSearchHits)
m.DateMetricIDsSearchCalls += atomic.LoadUint64(&db.dateMetricIDsSearchCalls)
m.DateMetricIDsSearchHits += atomic.LoadUint64(&db.dateMetricIDsSearchHits)
db.tb.UpdateMetrics(&m.TableMetrics)
db.doExtDB(func(extDB *indexDB) {
@@ -216,9 +266,7 @@ func (db *indexDB) decRef() {
}
logger.Infof("dropping indexDB %q", tbPath)
if err := os.RemoveAll(tbPath); err != nil {
logger.Panicf("FATAL: cannot remove %q: %s", tbPath, err)
}
fs.MustRemoveAll(tbPath)
logger.Infof("indexDB %q has been dropped", tbPath)
}
@@ -273,7 +321,7 @@ func (db *indexDB) putMetricNameToCache(metricID uint64, metricName []byte) {
db.metricNameCache.Set(key[:], metricName)
}
func marshalTagFiltersKey(dst []byte, tfss []*TagFilters) []byte {
func marshalTagFiltersKeyVersioned(dst []byte, tfss []*TagFilters) []byte {
prefix := atomic.LoadUint64(&tagFiltersKeyGen)
dst = encoding.MarshalUint64(dst, prefix)
for _, tfs := range tfss {
@@ -718,7 +766,7 @@ func (is *indexSearch) searchTagValues(tvs map[string]struct{}, prefix []byte, m
// up to two times - in db and extDB.
func (db *indexDB) GetSeriesCount() (uint64, error) {
is := db.getIndexSearch()
n, err := getSeriesCount(&is.ts, &is.kb)
n, err := is.getSeriesCount()
db.putIndexSearch(is)
if err != nil {
return 0, err
@@ -727,7 +775,7 @@ func (db *indexDB) GetSeriesCount() (uint64, error) {
var nExt uint64
ok := db.doExtDB(func(extDB *indexDB) {
is := extDB.getIndexSearch()
nExt, err = getSeriesCount(&is.ts, &is.kb)
nExt, err = is.getSeriesCount()
extDB.putIndexSearch(is)
})
if ok && err != nil {
@@ -872,7 +920,7 @@ func (db *indexDB) searchTSIDs(tfss []*TagFilters, tr TimeRange, maxMetrics int)
tfKeyBuf := tagFiltersKeyBufPool.Get()
defer tagFiltersKeyBufPool.Put(tfKeyBuf)
tfKeyBuf.B = marshalTagFiltersKey(tfKeyBuf.B[:0], tfss)
tfKeyBuf.B = marshalTagFiltersKeyVersioned(tfKeyBuf.B[:0], tfss)
tsids, ok := db.getFromTagCache(tfKeyBuf.B)
if ok {
// Fast path - tsids found in the cache.
@@ -945,7 +993,7 @@ func (is *indexSearch) getTSIDByMetricName(dst *TSID, metricName []byte) error {
if len(dmis) > 0 {
// Verify whether the dst is marked as deleted.
if _, deleted := dmis[dst.MetricID]; deleted {
// The dst is deleted. Continue seraching.
// The dst is deleted. Continue searching.
continue
}
}
@@ -1078,7 +1126,9 @@ func (is *indexSearch) getTSIDByMetricID(dst *TSID, metricID uint64) error {
return nil
}
func getSeriesCount(ts *mergeset.TableSearch, kb *bytesutil.ByteBuffer) (uint64, error) {
func (is *indexSearch) getSeriesCount() (uint64, error) {
ts := &is.ts
kb := &is.kb
var n uint64
kb.B = append(kb.B[:0], nsPrefixMetricIDToTSID)
ts.Seek(kb.B)
@@ -1095,9 +1145,9 @@ func getSeriesCount(ts *mergeset.TableSearch, kb *bytesutil.ByteBuffer) (uint64,
return n, nil
}
// searchMetricIDsMapByMetricNameMatch matches metricName values for the given srcMetricIDs against tfs
// updateMetricIDsByMetricNameMatch matches metricName values for the given srcMetricIDs against tfs
// and adds matching metrics to metricIDs.
func (is *indexSearch) searchMetricIDsMapByMetricNameMatch(metricIDs, srcMetricIDs map[uint64]struct{}, tfs []*tagFilter) error {
func (is *indexSearch) updateMetricIDsByMetricNameMatch(metricIDs, srcMetricIDs map[uint64]struct{}, tfs []*tagFilter) error {
// sort srcMetricIDs in order to speed up Seek below.
sortedMetricIDs := make([]uint64, 0, len(srcMetricIDs))
for metricID := range srcMetricIDs {
@@ -1132,7 +1182,51 @@ func (is *indexSearch) searchMetricIDsMapByMetricNameMatch(metricIDs, srcMetricI
return nil
}
func (is *indexSearch) getTagFilterWithMinMetricIDsMap(tfs *TagFilters, maxMetrics int) (*tagFilter, map[uint64]struct{}, error) {
func (is *indexSearch) getTagFilterWithMinMetricIDsCountAdaptive(tfs *TagFilters, maxMetrics int) (*tagFilter, map[uint64]struct{}, error) {
kb := &is.kb
kb.B = tfs.marshal(kb.B[:0])
kb.B = encoding.MarshalUint64(kb.B, uint64(maxMetrics))
if len(is.db.uselessTagFiltersCache.Get(nil, kb.B)) > 0 {
// Skip useless work below, since the tfs doesn't contain tag filters matching less than maxMetrics metrics.
return nil, nil, errTooManyMetrics
}
// Iteratively increase maxAllowedMetrics up to maxMetrics in order to limit
// the time required for founding the tag filter with minimum matching metrics.
maxAllowedMetrics := 16
if maxAllowedMetrics > maxMetrics {
maxAllowedMetrics = maxMetrics
}
for {
minTf, minMetricIDs, err := is.getTagFilterWithMinMetricIDsCount(tfs, maxAllowedMetrics)
if err != nil {
return nil, nil, err
}
if len(minMetricIDs) < maxAllowedMetrics {
// Found the tag filter with the minimum number of metrics.
return minTf, minMetricIDs, nil
}
// Too many metrics matched.
if maxAllowedMetrics >= maxMetrics {
// The tag filter with minimum matching metrics matches at least maxMetrics metrics.
kb.B = tfs.marshal(kb.B[:0])
kb.B = encoding.MarshalUint64(kb.B, uint64(maxMetrics))
is.db.uselessTagFiltersCache.Set(kb.B, []byte("1"))
return nil, nil, errTooManyMetrics
}
// Increase maxAllowedMetrics and try again.
maxAllowedMetrics *= 4
if maxAllowedMetrics > maxMetrics {
maxAllowedMetrics = maxMetrics
}
}
}
var errTooManyMetrics = errors.New("all the tag filters match too many metrics")
func (is *indexSearch) getTagFilterWithMinMetricIDsCount(tfs *TagFilters, maxMetrics int) (*tagFilter, map[uint64]struct{}, error) {
var minMetricIDs map[uint64]struct{}
var minTf *tagFilter
for i := range tfs.tfs {
@@ -1141,7 +1235,7 @@ func (is *indexSearch) getTagFilterWithMinMetricIDsMap(tfs *TagFilters, maxMetri
// Skip negative filters.
continue
}
metricIDs, err := is.getMetricIDsMapForTagFilter(tf, maxMetrics)
metricIDs, err := is.getMetricIDsForTagFilter(tf, maxMetrics)
if err != nil {
if err == errFallbackToMetricNameMatch {
// Skip tag filters requiring to scan for too many metrics.
@@ -1167,7 +1261,7 @@ func (is *indexSearch) getTagFilterWithMinMetricIDsMap(tfs *TagFilters, maxMetri
// There is no positive filter with small number of matching metrics.
// Create it, so it matches all the MetricIDs for tfs.commonPrefix.
metricIDs := make(map[uint64]struct{})
if err := is.getMetricIDsMapForCommonPrefix(metricIDs, tfs.commonPrefix, maxMetrics); err != nil {
if err := is.updateMetricIDsForCommonPrefix(metricIDs, tfs.commonPrefix, maxMetrics); err != nil {
return nil, nil, err
}
return nil, metricIDs, nil
@@ -1236,84 +1330,60 @@ func matchTagFilter(b []byte, tf *tagFilter) (bool, error) {
}
func (is *indexSearch) searchMetricIDs(tfss []*TagFilters, tr TimeRange, maxMetrics int) ([]uint64, error) {
metricIDsMap := make(map[uint64]struct{})
metricIDs := make(map[uint64]struct{})
for _, tfs := range tfss {
if len(tfs.tfs) == 0 {
// Return all the metric ids
if err := is.getMetricIDsMapForCommonPrefix(metricIDsMap, tfs.commonPrefix, maxMetrics+1); err != nil {
if err := is.updateMetricIDsForCommonPrefix(metricIDs, tfs.commonPrefix, maxMetrics+1); err != nil {
return nil, err
}
if len(metricIDsMap) > maxMetrics {
if len(metricIDs) > maxMetrics {
return nil, fmt.Errorf("the number or unique timeseries exceeds %d; either narrow down the search or increase -search.maxUniqueTimeseries", maxMetrics)
}
// Stop the iteration, since we cannot find more metric ids with the remaining tfss.
break
}
if err := is.searchMetricIDsMap(metricIDsMap, tfs, tr, maxMetrics+1); err != nil {
if err := is.updateMetricIDsForTagFilters(metricIDs, tfs, tr, maxMetrics+1); err != nil {
return nil, err
}
if len(metricIDsMap) > maxMetrics {
if len(metricIDs) > maxMetrics {
return nil, fmt.Errorf("the number or matching unique timeseries exceeds %d; either narrow down the search or increase -search.maxUniqueTimeseries", maxMetrics)
}
}
if len(metricIDsMap) == 0 {
if len(metricIDs) == 0 {
// Nothing found
return nil, nil
}
metricIDs := getSortedMetricIDs(metricIDsMap)
sortedMetricIDs := getSortedMetricIDs(metricIDs)
// Filter out deleted metricIDs.
dmis := is.db.getDeletedMetricIDs()
if len(dmis) > 0 {
metricIDsFiltered := metricIDs[:0]
for _, metricID := range metricIDs {
metricIDsFiltered := sortedMetricIDs[:0]
for _, metricID := range sortedMetricIDs {
if _, deleted := dmis[metricID]; !deleted {
metricIDsFiltered = append(metricIDsFiltered, metricID)
}
}
metricIDs = metricIDsFiltered
sortedMetricIDs = metricIDsFiltered
}
return metricIDs, nil
return sortedMetricIDs, nil
}
func (is *indexSearch) searchMetricIDsMap(metricIDs map[uint64]struct{}, tfs *TagFilters, tr TimeRange, maxMetrics int) error {
func (is *indexSearch) updateMetricIDsForTagFilters(metricIDs map[uint64]struct{}, tfs *TagFilters, tr TimeRange, maxMetrics int) error {
// Sort tag filters for faster ts.Seek below.
sort.Slice(tfs.tfs, func(i, j int) bool { return bytes.Compare(tfs.tfs[i].prefix, tfs.tfs[j].prefix) < 0 })
// Find the filter with minimum matching metrics.
// Iteratively increase maxAllowedMetrics up to maxMetrics in order to limit
// the time required for founding the tag filter with minimum matching metrics.
var minTf *tagFilter
var minMetricIDs map[uint64]struct{}
maxAllowedMetrics := 16
if maxAllowedMetrics > maxMetrics {
maxAllowedMetrics = maxMetrics
}
for {
var err error
minTf, minMetricIDs, err = is.getTagFilterWithMinMetricIDsMap(tfs, maxAllowedMetrics)
if err != nil {
minTf, minMetricIDs, err := is.getTagFilterWithMinMetricIDsCountAdaptive(tfs, maxMetrics)
if err != nil {
if err != errTooManyMetrics {
return err
}
if len(minMetricIDs) < maxAllowedMetrics {
// Found the tag filter with the minimum number of metrics.
break
}
// Too many metrics matched.
if maxAllowedMetrics < maxMetrics {
// Increase maxAllowedMetrics and try again.
maxAllowedMetrics *= 4
if maxAllowedMetrics > maxMetrics {
maxAllowedMetrics = maxMetrics
}
continue
}
// All the tag filters match too many metrics.
// The tag filter with minimum matching metrics matches at least maxMetrics.
//
// Slow path: try filtering the matching metrics by time range.
// This should work well for cases when old metrics are constantly substituted
// by big number of new metrics. For example, prometheus-operator creates many new
@@ -1324,11 +1394,8 @@ func (is *indexSearch) searchMetricIDsMap(metricIDs map[uint64]struct{}, tfs *Ta
maxTimeRangeMetrics := 20 * maxMetrics
metricIDsForTimeRange, err := is.getMetricIDsForTimeRange(tr, maxTimeRangeMetrics+1)
if err == errMissingMetricIDsForDate {
// Give up.
for metricID := range minMetricIDs {
metricIDs[metricID] = struct{}{}
}
return nil
return fmt.Errorf("cannot find tag filter matching less up to %d time series; either increase -search.maxUniqueTimeseries or use more specific tag filters",
maxMetrics)
}
if err != nil {
return err
@@ -1339,7 +1406,6 @@ func (is *indexSearch) searchMetricIDsMap(metricIDs map[uint64]struct{}, tfs *Ta
}
minMetricIDs = metricIDsForTimeRange
minTf = nil
break
}
// Find intersection of minTf with other tfs.
@@ -1349,7 +1415,7 @@ func (is *indexSearch) searchMetricIDsMap(metricIDs map[uint64]struct{}, tfs *Ta
if tf == minTf {
continue
}
mIDs, err := is.intersectMetricIDsMapForTagFilter(tf, minMetricIDs)
mIDs, err := is.intersectMetricIDsWithTagFilter(tf, minMetricIDs)
if err == errFallbackToMetricNameMatch {
// The tag filter requires too many index scans. Postpone it,
// so tag filters with lower number of index scans may be applied.
@@ -1362,9 +1428,9 @@ func (is *indexSearch) searchMetricIDsMap(metricIDs map[uint64]struct{}, tfs *Ta
minMetricIDs = mIDs
}
for i, tf := range tfsPostponed {
mIDs, err := is.intersectMetricIDsMapForTagFilter(tf, minMetricIDs)
mIDs, err := is.intersectMetricIDsWithTagFilter(tf, minMetricIDs)
if err == errFallbackToMetricNameMatch {
return is.searchMetricIDsMapByMetricNameMatch(metricIDs, minMetricIDs, tfsPostponed[i:])
return is.updateMetricIDsByMetricNameMatch(metricIDs, minMetricIDs, tfsPostponed[i:])
}
if err != nil {
return err
@@ -1377,14 +1443,14 @@ func (is *indexSearch) searchMetricIDsMap(metricIDs map[uint64]struct{}, tfs *Ta
return nil
}
func (is *indexSearch) getMetricIDsMapForTagFilter(tf *tagFilter, maxMetrics int) (map[uint64]struct{}, error) {
func (is *indexSearch) getMetricIDsForTagFilter(tf *tagFilter, maxMetrics int) (map[uint64]struct{}, error) {
if tf.isNegative {
logger.Panicf("BUG: isNegative must be false")
}
metricIDs := make(map[uint64]struct{}, maxMetrics)
if len(tf.orSuffixes) > 0 {
// Fast path for orSuffixes - seek for rows for each value from orSuffxies.
if err := is.updateMetricIDsMapForOrSuffixesNoFilter(tf, maxMetrics, metricIDs); err != nil {
if err := is.updateMetricIDsForOrSuffixesNoFilter(tf, maxMetrics, metricIDs); err != nil {
return nil, err
}
return metricIDs, nil
@@ -1430,7 +1496,7 @@ func (is *indexSearch) getMetricIDsMapForTagFilter(tf *tagFilter, maxMetrics int
return metricIDs, nil
}
func (is *indexSearch) updateMetricIDsMapForOrSuffixesNoFilter(tf *tagFilter, maxMetrics int, metricIDs map[uint64]struct{}) error {
func (is *indexSearch) updateMetricIDsForOrSuffixesNoFilter(tf *tagFilter, maxMetrics int, metricIDs map[uint64]struct{}) error {
if tf.isNegative {
logger.Panicf("BUG: isNegative must be false")
}
@@ -1440,7 +1506,7 @@ func (is *indexSearch) updateMetricIDsMapForOrSuffixesNoFilter(tf *tagFilter, ma
kb.B = append(kb.B[:0], tf.prefix...)
kb.B = append(kb.B, orSuffix...)
kb.B = append(kb.B, tagSeparatorChar)
if err := is.updateMetricIDsMapForOrSuffixNoFilter(kb.B, maxMetrics, metricIDs); err != nil {
if err := is.updateMetricIDsForOrSuffixNoFilter(kb.B, maxMetrics, metricIDs); err != nil {
return err
}
if len(metricIDs) >= maxMetrics {
@@ -1450,7 +1516,7 @@ func (is *indexSearch) updateMetricIDsMapForOrSuffixesNoFilter(tf *tagFilter, ma
return nil
}
func (is *indexSearch) updateMetricIDsMapForOrSuffixesWithFilter(tf *tagFilter, metricIDs, filter map[uint64]struct{}) error {
func (is *indexSearch) updateMetricIDsForOrSuffixesWithFilter(tf *tagFilter, metricIDs, filter map[uint64]struct{}) error {
sortedFilter := getSortedMetricIDs(filter)
kb := kbPool.Get()
defer kbPool.Put(kb)
@@ -1458,14 +1524,14 @@ func (is *indexSearch) updateMetricIDsMapForOrSuffixesWithFilter(tf *tagFilter,
kb.B = append(kb.B[:0], tf.prefix...)
kb.B = append(kb.B, orSuffix...)
kb.B = append(kb.B, tagSeparatorChar)
if err := is.updateMetricIDsMapForOrSuffixWithFilter(kb.B, metricIDs, sortedFilter, tf.isNegative); err != nil {
if err := is.updateMetricIDsForOrSuffixWithFilter(kb.B, metricIDs, sortedFilter, tf.isNegative); err != nil {
return err
}
}
return nil
}
func (is *indexSearch) updateMetricIDsMapForOrSuffixNoFilter(prefix []byte, maxMetrics int, metricIDs map[uint64]struct{}) error {
func (is *indexSearch) updateMetricIDsForOrSuffixNoFilter(prefix []byte, maxMetrics int, metricIDs map[uint64]struct{}) error {
ts := &is.ts
maxLoops := maxMetrics * maxIndexScanLoopsPerMetric
loops := 0
@@ -1492,7 +1558,7 @@ func (is *indexSearch) updateMetricIDsMapForOrSuffixNoFilter(prefix []byte, maxM
return nil
}
func (is *indexSearch) updateMetricIDsMapForOrSuffixWithFilter(prefix []byte, metricIDs map[uint64]struct{}, sortedFilter []uint64, isNegative bool) error {
func (is *indexSearch) updateMetricIDsForOrSuffixWithFilter(prefix []byte, metricIDs map[uint64]struct{}, sortedFilter []uint64, isNegative bool) error {
ts := &is.ts
kb := &is.kb
for {
@@ -1533,7 +1599,7 @@ func (is *indexSearch) updateMetricIDsMapForOrSuffixWithFilter(prefix []byte, me
return nil
}
var errFallbackToMetricNameMatch = errors.New("fall back to searchMetricIDsMapByMetricNameMatch because of too many index scan loops")
var errFallbackToMetricNameMatch = errors.New("fall back to updateMetricIDsByMetricNameMatch because of too many index scan loops")
var errMissingMetricIDsForDate = errors.New("missing metricIDs for date")
@@ -1541,6 +1607,16 @@ func (is *indexSearch) getMetricIDsForTimeRange(tr TimeRange, maxMetrics int) (m
if tr.isZero() {
return nil, errMissingMetricIDsForDate
}
atomic.AddUint64(&is.db.recentHourMetricIDsSearchCalls, 1)
if metricIDs, ok := is.getMetricIDsForRecentHours(tr, maxMetrics); ok {
// Fast path: tr covers the current and / or the previous hour.
// Return the full list of metric ids for this time range.
atomic.AddUint64(&is.db.recentHourMetricIDsSearchHits, 1)
return metricIDs, nil
}
// Slow path: collect the metric ids for all the days covering the given tr.
atomic.AddUint64(&is.db.dateMetricIDsSearchCalls, 1)
minDate := tr.MinTimestamp / msecPerDay
maxDate := tr.MaxTimestamp / msecPerDay
if maxDate-minDate > 40 {
@@ -1554,9 +1630,64 @@ func (is *indexSearch) getMetricIDsForTimeRange(tr TimeRange, maxMetrics int) (m
}
minDate++
}
atomic.AddUint64(&is.db.dateMetricIDsSearchHits, 1)
return metricIDs, nil
}
func (is *indexSearch) getMetricIDsForRecentHours(tr TimeRange, maxMetrics int) (map[uint64]struct{}, bool) {
minHour := uint64(tr.MinTimestamp) / msecPerHour
maxHour := uint64(tr.MaxTimestamp) / msecPerHour
if is.db.currHourMetricIDs == nil {
return nil, false
}
hmCurr := is.db.currHourMetricIDs.Load().(*hourMetricIDs)
if maxHour == hmCurr.hour && minHour == maxHour && hmCurr.isFull {
// The tr fits the current hour.
// Return a copy of hmCurr.m, because the caller may modify
// the returned map.
if len(hmCurr.m) > maxMetrics {
return nil, false
}
return getMetricIDsCopy(hmCurr.m), true
}
if is.db.prevHourMetricIDs == nil {
return nil, false
}
hmPrev := is.db.prevHourMetricIDs.Load().(*hourMetricIDs)
if maxHour == hmPrev.hour && minHour == maxHour && hmPrev.isFull {
// The tr fits the previous hour.
// Return a copy of hmPrev.m, because the caller may modify
// the returned map.
if len(hmPrev.m) > maxMetrics {
return nil, false
}
return getMetricIDsCopy(hmPrev.m), true
}
if maxHour == hmCurr.hour && minHour == hmPrev.hour && hmCurr.isFull && hmPrev.isFull {
// The tr spans the previous and the current hours.
if len(hmCurr.m)+len(hmPrev.m) > maxMetrics {
return nil, false
}
metricIDs := make(map[uint64]struct{}, len(hmCurr.m)+len(hmPrev.m))
for metricID := range hmCurr.m {
metricIDs[metricID] = struct{}{}
}
for metricID := range hmPrev.m {
metricIDs[metricID] = struct{}{}
}
return metricIDs, true
}
return nil, false
}
func getMetricIDsCopy(src map[uint64]struct{}) map[uint64]struct{} {
dst := make(map[uint64]struct{}, len(src))
for metricID := range src {
dst[metricID] = struct{}{}
}
return dst
}
func (db *indexDB) storeDateMetricID(date, metricID uint64) error {
is := db.getIndexSearch()
ok, err := is.hasDateMetricID(date, metricID)
@@ -1629,7 +1760,7 @@ func (is *indexSearch) getMetricIDsForDate(date uint64, metricIDs map[uint64]str
return nil
}
func (is *indexSearch) getMetricIDsMapForCommonPrefix(metricIDs map[uint64]struct{}, commonPrefix []byte, maxMetrics int) error {
func (is *indexSearch) updateMetricIDsForCommonPrefix(metricIDs map[uint64]struct{}, commonPrefix []byte, maxMetrics int) error {
ts := &is.ts
ts.Seek(commonPrefix)
for len(metricIDs) < maxMetrics && ts.NextItem() {
@@ -1654,11 +1785,11 @@ func (is *indexSearch) getMetricIDsMapForCommonPrefix(metricIDs map[uint64]struc
}
// The maximum number of index scan loops per already found metric.
// Bigger number of loops is slower than searchMetricIDsMapByMetricNameMatch
// Bigger number of loops is slower than updateMetricIDsByMetricNameMatch
// over the found metrics.
const maxIndexScanLoopsPerMetric = 32
func (is *indexSearch) intersectMetricIDsMapForTagFilter(tf *tagFilter, filter map[uint64]struct{}) (map[uint64]struct{}, error) {
func (is *indexSearch) intersectMetricIDsWithTagFilter(tf *tagFilter, filter map[uint64]struct{}) (map[uint64]struct{}, error) {
if len(filter) == 0 {
return nil, nil
}
@@ -1668,7 +1799,7 @@ func (is *indexSearch) intersectMetricIDsMapForTagFilter(tf *tagFilter, filter m
}
if len(tf.orSuffixes) > 0 {
// Fast path for orSuffixes - seek for rows for each value from orSuffixes.
if err := is.updateMetricIDsMapForOrSuffixesWithFilter(tf, metricIDs, filter); err != nil {
if err := is.updateMetricIDsForOrSuffixesWithFilter(tf, metricIDs, filter); err != nil {
return nil, err
}
return metricIDs, nil

View File

@@ -61,7 +61,7 @@ func TestIndexDBOpenClose(t *testing.T) {
defer metricIDCache.Reset()
defer metricNameCache.Reset()
for i := 0; i < 5; i++ {
db, err := openIndexDB("test-index-db", metricIDCache, metricNameCache)
db, err := openIndexDB("test-index-db", metricIDCache, metricNameCache, nil, nil)
if err != nil {
t.Fatalf("cannot open indexDB: %s", err)
}
@@ -83,7 +83,7 @@ func TestIndexDB(t *testing.T) {
defer metricIDCache.Reset()
defer metricNameCache.Reset()
dbName := "test-index-db-serial"
db, err := openIndexDB(dbName, metricIDCache, metricNameCache)
db, err := openIndexDB(dbName, metricIDCache, metricNameCache, nil, nil)
if err != nil {
t.Fatalf("cannot open indexDB: %s", err)
}
@@ -113,7 +113,7 @@ func TestIndexDB(t *testing.T) {
// Re-open the db and verify it works as expected.
db.MustClose()
db, err = openIndexDB(dbName, metricIDCache, metricNameCache)
db, err = openIndexDB(dbName, metricIDCache, metricNameCache, nil, nil)
if err != nil {
t.Fatalf("cannot open indexDB: %s", err)
}
@@ -134,7 +134,7 @@ func TestIndexDB(t *testing.T) {
defer metricIDCache.Reset()
defer metricNameCache.Reset()
dbName := "test-index-db-concurrent"
db, err := openIndexDB(dbName, metricIDCache, metricNameCache)
db, err := openIndexDB(dbName, metricIDCache, metricNameCache, nil, nil)
if err != nil {
t.Fatalf("cannot open indexDB: %s", err)
}
@@ -382,6 +382,19 @@ func testIndexDBCheckTSIDByName(db *indexDB, mns []MetricName, tsids []TSID, isC
}
}
// Check timerseriesCounters only for serial test.
// Concurrent test may create duplicate timeseries, so GetSeriesCount
// would return more timeseries than needed.
if !isConcurrent {
n, err := db.GetSeriesCount()
if err != nil {
return fmt.Errorf("unexpected error in GetSeriesCount(): %s", err)
}
if n != uint64(len(timeseriesCounters)) {
return fmt.Errorf("unexpected GetSeriesCount(); got %d; want %d", n, uint64(len(timeseriesCounters)))
}
}
// Try tag filters.
for i := range mns {
mn := &mns[i]

View File

@@ -17,7 +17,7 @@ func BenchmarkIndexDBAddTSIDs(b *testing.B) {
defer metricIDCache.Reset()
defer metricNameCache.Reset()
const dbName = "bench-index-db-add-tsids"
db, err := openIndexDB(dbName, metricIDCache, metricNameCache)
db, err := openIndexDB(dbName, metricIDCache, metricNameCache, nil, nil)
if err != nil {
b.Fatalf("cannot open indexDB: %s", err)
}
@@ -77,7 +77,7 @@ func BenchmarkIndexDBSearchTSIDs(b *testing.B) {
defer metricIDCache.Reset()
defer metricNameCache.Reset()
const dbName = "bench-index-db-search-tsids"
db, err := openIndexDB(dbName, metricIDCache, metricNameCache)
db, err := openIndexDB(dbName, metricIDCache, metricNameCache, nil, nil)
if err != nil {
b.Fatalf("cannot open indexDB: %s", err)
}
@@ -148,7 +148,7 @@ func BenchmarkIndexDBGetTSIDs(b *testing.B) {
defer metricIDCache.Reset()
defer metricNameCache.Reset()
const dbName = "bench-index-db-get-tsids"
db, err := openIndexDB(dbName, metricIDCache, metricNameCache)
db, err := openIndexDB(dbName, metricIDCache, metricNameCache, nil, nil)
if err != nil {
b.Fatalf("cannot open indexDB: %s", err)
}

View File

@@ -212,14 +212,8 @@ func createPartition(timestamp int64, smallPartitionsPath, bigPartitionsPath str
// The pt must be detached from table before calling pt.Drop.
func (pt *partition) Drop() {
logger.Infof("dropping partition %q at smallPartsPath=%q, bigPartsPath=%q", pt.name, pt.smallPartsPath, pt.bigPartsPath)
if err := os.RemoveAll(pt.smallPartsPath); err != nil {
logger.Panicf("FATAL: cannot remove small parts directory %q: %s", pt.smallPartsPath, err)
}
if err := os.RemoveAll(pt.bigPartsPath); err != nil {
logger.Panicf("FATAL: cannot remove big parts directory %q: %s", pt.bigPartsPath, err)
}
fs.MustRemoveAll(pt.smallPartsPath)
fs.MustRemoveAll(pt.bigPartsPath)
logger.Infof("partition %q has been dropped", pt.name)
}
@@ -599,7 +593,7 @@ func (pt *partition) MustClose() {
logger.Infof("%d inmemory parts have been flushed to files in %s on %q", len(pws), time.Since(startTime), pt.smallPartsPath)
// Remove references to smallParts from the pt, so they may be eventually closed
// after all the seraches are done.
// after all the searches are done.
pt.partsLock.Lock()
smallParts := pt.smallParts
pt.smallParts = nil
@@ -1223,13 +1217,9 @@ func openParts(pathPrefix1, pathPrefix2, path string) ([]*partWrapper, error) {
}
txnDir := path + "/txn"
if err := os.RemoveAll(txnDir); err != nil {
return nil, fmt.Errorf("cannot delete transaction directory %q: %s", txnDir, err)
}
fs.MustRemoveAll(txnDir)
tmpDir := path + "/tmp"
if err := os.RemoveAll(tmpDir); err != nil {
return nil, fmt.Errorf("cannot remove temporary directory %q: %s", tmpDir, err)
}
fs.MustRemoveAll(tmpDir)
if err := createPartitionDirs(path); err != nil {
return nil, fmt.Errorf("cannot create directories for partition %q: %s", path, err)
}
@@ -1342,8 +1332,8 @@ func (pt *partition) createSnapshot(srcDir, dstDir string) error {
}
}
fs.SyncPath(dstDir)
fs.SyncPath(filepath.Dir(dstDir))
fs.MustSyncPath(dstDir)
fs.MustSyncPath(filepath.Dir(dstDir))
return nil
}
@@ -1408,9 +1398,7 @@ func runTransaction(txnLock *sync.RWMutex, pathPrefix1, pathPrefix2, txnPath str
if err != nil {
return fmt.Errorf("invalid path to remove: %s", err)
}
if err := os.RemoveAll(path); err != nil {
return fmt.Errorf("cannot remove %q: %s", path, err)
}
fs.MustRemoveAll(path)
}
// Move the new part to new directory.
@@ -1438,14 +1426,12 @@ func runTransaction(txnLock *sync.RWMutex, pathPrefix1, pathPrefix2, txnPath str
}
} else {
// Just remove srcPath.
if err := os.RemoveAll(srcPath); err != nil {
return fmt.Errorf("cannot remove %q: %s", srcPath, err)
}
fs.MustRemoveAll(srcPath)
}
// Flush pathPrefix* directory metadata to the underying storage.
fs.SyncPath(pathPrefix1)
fs.SyncPath(pathPrefix2)
fs.MustSyncPath(pathPrefix1)
fs.MustSyncPath(pathPrefix2)
// Remove the transaction file.
if err := os.Remove(txnPath); err != nil {
@@ -1487,6 +1473,6 @@ func createPartitionDirs(path string) error {
if err := fs.MkdirAllFailIfExist(tmpPath); err != nil {
return fmt.Errorf("cannot create tmp directory %q: %s", tmpPath, err)
}
fs.SyncPath(path)
fs.MustSyncPath(path)
return nil
}

View File

@@ -112,15 +112,15 @@ func testAppendPartsToMerge(t *testing.T, maxPartsToMerge int, initialRowsCount,
// Verify appending to prefix
prefix := []*partWrapper{
&partWrapper{
{
p: &part{
ph: partHeader{
RowsCount: 1234,
},
},
},
&partWrapper{},
&partWrapper{},
{},
{},
}
pms = appendPartsToMerge(prefix, pws, maxPartsToMerge, 1e9)
if !reflect.DeepEqual(pms[:len(prefix)], prefix) {

View File

@@ -19,7 +19,7 @@ type rawRow struct {
// Value is time series value for the given timestamp.
Value float64
// PrecisionBits is the number of the siginificant bits in the Value
// PrecisionBits is the number of the significant bits in the Value
// to store. Possible values are [1..64].
// 1 means max. 50% error, 2 - 25%, 3 - 12.5%, 64 means no error, i.e.
// Value stored without information loss.

View File

@@ -18,6 +18,7 @@ import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fs"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/memory"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/timerpool"
"github.com/VictoriaMetrics/fastcache"
"golang.org/x/sys/unix"
)
@@ -30,7 +31,7 @@ type Storage struct {
cachePath string
retentionMonths int
// lock file for excluse access to the storage on the given path.
// lock file for exclusive access to the storage on the given path.
flockF *os.File
idbCurr atomic.Value
@@ -49,8 +50,20 @@ type Storage struct {
// dateMetricIDCache is (Date, MetricID) cache.
dateMetricIDCache *fastcache.Cache
stop chan struct{}
retentionWatcherWG sync.WaitGroup
// Fast cache for MetricID values occured during the current hour.
currHourMetricIDs atomic.Value
// Fast cache for MetricID values occured during the previous hour.
prevHourMetricIDs atomic.Value
// Pending MetricID values to be added to currHourMetricIDs.
pendingHourMetricIDsLock sync.Mutex
pendingHourMetricIDs map[uint64]struct{}
stop chan struct{}
currHourMetricIDsUpdaterWG sync.WaitGroup
retentionWatcherWG sync.WaitGroup
}
// OpenStorage opens storage on the given path with the given number of retention months.
@@ -105,7 +118,7 @@ func OpenStorage(path string, retentionMonths int) (*Storage, error) {
if err := fs.MkdirAllIfNotExist(idbSnapshotsPath); err != nil {
return nil, fmt.Errorf("cannot create %q: %s", idbSnapshotsPath, err)
}
idbCurr, idbPrev, err := openIndexDBTables(idbPath, s.metricIDCache, s.metricNameCache)
idbCurr, idbPrev, err := openIndexDBTables(idbPath, s.metricIDCache, s.metricNameCache, &s.currHourMetricIDs, &s.prevHourMetricIDs)
if err != nil {
return nil, fmt.Errorf("cannot open indexdb tables at %q: %s", idbPath, err)
}
@@ -121,6 +134,10 @@ func OpenStorage(path string, retentionMonths int) (*Storage, error) {
}
s.tb = tb
s.currHourMetricIDs.Store(&hourMetricIDs{})
s.pendingHourMetricIDs = make(map[uint64]struct{})
s.startCurrHourMetricIDsUpdater()
s.startRetentionWatcher()
return s, nil
@@ -164,7 +181,7 @@ func (s *Storage) CreateSnapshot() (string, error) {
if err := fs.SymlinkRelative(bigDir, dstBigDir); err != nil {
return "", fmt.Errorf("cannot create symlink from %q to %q: %s", bigDir, dstBigDir, err)
}
fs.SyncPath(dstDataDir)
fs.MustSyncPath(dstDataDir)
idbSnapshot := fmt.Sprintf("%s/indexdb/snapshots/%s", s.path, snapshotName)
idb := s.idb()
@@ -184,8 +201,8 @@ func (s *Storage) CreateSnapshot() (string, error) {
return "", fmt.Errorf("cannot create symlink from %q to %q: %s", idbSnapshot, dstIdbDir, err)
}
fs.SyncPath(dstDir)
fs.SyncPath(srcDir + "/snapshots")
fs.MustSyncPath(dstDir)
fs.MustSyncPath(srcDir + "/snapshots")
logger.Infof("created Storage snapshot for %q at %q in %s", srcDir, dstDir, time.Since(startTime))
return snapshotName, nil
@@ -229,8 +246,8 @@ func (s *Storage) DeleteSnapshot(snapshotName string) error {
s.tb.MustDeleteSnapshot(snapshotName)
idbPath := fmt.Sprintf("%s/indexdb/snapshots/%s", s.path, snapshotName)
fs.MustRemoveAllSynced(idbPath)
fs.MustRemoveAllSynced(snapshotPath)
fs.MustRemoveAll(idbPath)
fs.MustRemoveAll(snapshotPath)
logger.Infof("deleted snapshot %q in %s", snapshotPath, time.Since(startTime))
@@ -340,11 +357,34 @@ func (s *Storage) retentionWatcher() {
}
}
func (s *Storage) startCurrHourMetricIDsUpdater() {
s.currHourMetricIDsUpdaterWG.Add(1)
go func() {
s.currHourMetricIDsUpdater()
s.currHourMetricIDsUpdaterWG.Done()
}()
}
var currHourMetricIDsUpdateInterval = time.Second * 10
func (s *Storage) currHourMetricIDsUpdater() {
t := time.NewTimer(currHourMetricIDsUpdateInterval)
for {
select {
case <-s.stop:
return
case <-t.C:
s.updateCurrHourMetricIDs()
t.Reset(currHourMetricIDsUpdateInterval)
}
}
}
func (s *Storage) mustRotateIndexDB() {
// Create new indexdb table.
newTableName := nextIndexDBTableName()
idbNewPath := s.path + "/indexdb/" + newTableName
idbNew, err := openIndexDB(idbNewPath, s.metricIDCache, s.metricNameCache)
idbNew, err := openIndexDB(idbNewPath, s.metricIDCache, s.metricNameCache, &s.currHourMetricIDs, &s.prevHourMetricIDs)
if err != nil {
logger.Panicf("FATAL: cannot create new indexDB at %q: %s", idbNewPath, err)
}
@@ -361,7 +401,7 @@ func (s *Storage) mustRotateIndexDB() {
s.idbCurr.Store(idbNew)
// Persist changes on the file system.
fs.SyncPath(s.path)
fs.MustSyncPath(s.path)
// Flush tsidCache, so idbNew can be populated with fresh data.
s.tsidCache.Reset()
@@ -378,6 +418,7 @@ func (s *Storage) MustClose() {
close(s.stop)
s.retentionWatcherWG.Wait()
s.currHourMetricIDsUpdaterWG.Wait()
s.tb.MustClose()
s.idb().MustClose()
@@ -475,6 +516,39 @@ func (s *Storage) SearchTagValues(tagKey []byte, maxTagValues int) ([]string, er
return s.idb().SearchTagValues(tagKey, maxTagValues)
}
// SearchTagEntries returns a list of (tagName -> tagValues) for (accountID, projectID).
func (s *Storage) SearchTagEntries(maxTagKeys, maxTagValues int) ([]TagEntry, error) {
idb := s.idb()
keys, err := idb.SearchTagKeys(maxTagKeys)
if err != nil {
return nil, fmt.Errorf("cannot search tag keys: %s", err)
}
// Sort keys for faster seeks below
sort.Strings(keys)
tes := make([]TagEntry, len(keys))
for i, key := range keys {
values, err := idb.SearchTagValues([]byte(key), maxTagValues)
if err != nil {
return nil, fmt.Errorf("cannot search values for tag %q: %s", key, err)
}
te := &tes[i]
te.Key = key
te.Values = values
}
return tes, nil
}
// TagEntry contains (tagName -> tagValues) mapping
type TagEntry struct {
// Key is tagName
Key string
// Values contains all the values for Key.
Values []string
}
// GetSeriesCount returns the approximate number of unique time series.
//
// It includes the deleted series too and may count the same series
@@ -553,12 +627,13 @@ func (s *Storage) AddRows(mrs []MetricRow, precisionBits uint8) error {
// Limit the number of concurrent goroutines that may add rows to the storage.
// This should prevent from out of memory errors and CPU trashing when too many
// goroutines call AddRows.
t := time.NewTimer(addRowsTimeout)
t := timerpool.Get(addRowsTimeout)
select {
case addRowsConcurrencyCh <- struct{}{}:
t.Stop()
timerpool.Put(t)
defer func() { <-addRowsConcurrencyCh }()
case <-t.C:
timerpool.Put(t)
return fmt.Errorf("Cannot add %d rows to storage in %s, since it is overloaded with %d concurrent writers. Add more CPUs or reduce load",
len(mrs), addRowsTimeout, cap(addRowsConcurrencyCh))
}
@@ -656,13 +731,14 @@ func (s *Storage) add(rows []rawRow, mrs []MetricRow, precisionBits uint8) ([]ra
errors = s.updateDateMetricIDCache(rows, errors)
if len(errors) > 0 {
// Return only the first error, since it has no sense in returning all errors.
return rows, fmt.Errorf("errors occured during rows addition: %s", errors[0])
return rows, fmt.Errorf("errors occurred during rows addition: %s", errors[0])
}
return rows, nil
}
func (s *Storage) updateDateMetricIDCache(rows []rawRow, errors []error) []error {
var date uint64
var hour uint64
var prevTimestamp int64
kb := kbPool.Get()
defer kbPool.Put(kb)
@@ -674,17 +750,30 @@ func (s *Storage) updateDateMetricIDCache(rows []rawRow, errors []error) []error
r := &rows[i]
if r.Timestamp != prevTimestamp {
date = uint64(r.Timestamp) / msecPerDay
hour = uint64(r.Timestamp) / msecPerHour
prevTimestamp = r.Timestamp
}
metricID := r.TSID.MetricID
hm := s.currHourMetricIDs.Load().(*hourMetricIDs)
if hour == hm.hour {
// The r belongs to the current hour. Check for the current hour cache.
if _, ok := hm.m[metricID]; ok {
// Fast path: the metricID is in the current hour cache.
continue
}
s.pendingHourMetricIDsLock.Lock()
s.pendingHourMetricIDs[metricID] = struct{}{}
s.pendingHourMetricIDsLock.Unlock()
}
// Slower path: check global cache for (date, metricID) entry.
a[0] = date
a[1] = metricID
if s.dateMetricIDCache.Has(keyBuf) {
// Fast path: the (date, metricID) entry is in the cache.
continue
}
// Slow path: store the entry in the cache and in the indexDB.
// Slow path: store the entry in the (date, metricID) cache and in the indexDB.
// It is OK if the (date, metricID) entry is added multiple times to db
// by concurrent goroutines.
s.dateMetricIDCache.Set(keyBuf, nil)
@@ -696,6 +785,54 @@ func (s *Storage) updateDateMetricIDCache(rows []rawRow, errors []error) []error
return errors
}
func (s *Storage) updateCurrHourMetricIDs() {
hm := s.currHourMetricIDs.Load().(*hourMetricIDs)
s.pendingHourMetricIDsLock.Lock()
newMetricIDsLen := len(s.pendingHourMetricIDs)
s.pendingHourMetricIDsLock.Unlock()
hour := uint64(timestampFromTime(time.Now())) / msecPerHour
if newMetricIDsLen == 0 && hm.hour == hour {
// Fast path: nothing to update.
return
}
// Slow path: hm.m must be updated with non-empty s.pendingHourMetricIDs.
var m map[uint64]struct{}
isFull := hm.isFull
if hm.hour == hour {
m = make(map[uint64]struct{}, len(hm.m)+newMetricIDsLen)
for metricID := range hm.m {
m[metricID] = struct{}{}
}
} else {
m = make(map[uint64]struct{}, newMetricIDsLen)
isFull = true
}
s.pendingHourMetricIDsLock.Lock()
newMetricIDs := s.pendingHourMetricIDs
s.pendingHourMetricIDs = make(map[uint64]struct{}, len(newMetricIDs))
s.pendingHourMetricIDsLock.Unlock()
for metricID := range newMetricIDs {
m[metricID] = struct{}{}
}
hmNew := &hourMetricIDs{
m: m,
hour: hour,
isFull: isFull,
}
s.currHourMetricIDs.Store(hmNew)
if hm.hour != hour {
s.prevHourMetricIDs.Store(hm)
}
}
type hourMetricIDs struct {
m map[uint64]struct{}
hour uint64
isFull bool
}
func (s *Storage) getTSIDFromCache(dst *TSID, metricName []byte) bool {
buf := (*[unsafe.Sizeof(*dst)]byte)(unsafe.Pointer(dst))[:]
buf = s.tsidCache.Get(buf[:0], metricName)
@@ -707,7 +844,7 @@ func (s *Storage) putTSIDToCache(tsid *TSID, metricName []byte) {
s.tsidCache.Set(metricName, buf)
}
func openIndexDBTables(path string, metricIDCache, metricNameCache *fastcache.Cache) (curr, prev *indexDB, err error) {
func openIndexDBTables(path string, metricIDCache, metricNameCache *fastcache.Cache, currHourMetricIDs, prevHourMetricIDs *atomic.Value) (curr, prev *indexDB, err error) {
if err := fs.MkdirAllIfNotExist(path); err != nil {
return nil, nil, fmt.Errorf("cannot create directory %q: %s", path, err)
}
@@ -756,24 +893,22 @@ func openIndexDBTables(path string, metricIDCache, metricNameCache *fastcache.Ca
for _, tn := range tableNames[:len(tableNames)-2] {
pathToRemove := path + "/" + tn
logger.Infof("removing obsolete indexdb dir %q...", pathToRemove)
if err := os.RemoveAll(pathToRemove); err != nil {
return nil, nil, fmt.Errorf("cannot remove obsolete indexdb dir %q: %s", pathToRemove, err)
}
fs.MustRemoveAll(pathToRemove)
logger.Infof("removed obsolete indexdb dir %q", pathToRemove)
}
// Persist changes on the file system.
fs.SyncPath(path)
fs.MustSyncPath(path)
// Open the last two tables.
currPath := path + "/" + tableNames[len(tableNames)-1]
curr, err = openIndexDB(currPath, metricIDCache, metricNameCache)
curr, err = openIndexDB(currPath, metricIDCache, metricNameCache, currHourMetricIDs, prevHourMetricIDs)
if err != nil {
return nil, nil, fmt.Errorf("cannot open curr indexdb table at %q: %s", currPath, err)
}
prevPath := path + "/" + tableNames[len(tableNames)-2]
prev, err = openIndexDB(prevPath, metricIDCache, metricNameCache)
prev, err = openIndexDB(prevPath, metricIDCache, metricNameCache, currHourMetricIDs, prevHourMetricIDs)
if err != nil {
curr.MustClose()
return nil, nil, fmt.Errorf("cannot open prev indexdb table at %q: %s", prevPath, err)

View File

@@ -11,6 +11,184 @@ import (
"time"
)
func TestUpdateCurrHourMetricIDs(t *testing.T) {
newStorage := func() *Storage {
var s Storage
s.currHourMetricIDs.Store(&hourMetricIDs{})
s.prevHourMetricIDs.Store(&hourMetricIDs{})
s.pendingHourMetricIDs = make(map[uint64]struct{})
return &s
}
t.Run("empty_pedning_metric_ids_stale_curr_hour", func(t *testing.T) {
s := newStorage()
hour := uint64(timestampFromTime(time.Now())) / msecPerHour
hmOrig := &hourMetricIDs{
m: map[uint64]struct{}{
12: {},
34: {},
},
hour: 123,
}
s.currHourMetricIDs.Store(hmOrig)
s.updateCurrHourMetricIDs()
hmCurr := s.currHourMetricIDs.Load().(*hourMetricIDs)
if hmCurr.hour != hour {
// It is possible new hour occured. Update the hour and verify it again.
hour = uint64(timestampFromTime(time.Now())) / msecPerHour
if hmCurr.hour != hour {
t.Fatalf("unexpected hmCurr.hour; got %d; want %d", hmCurr.hour, hour)
}
}
if len(hmCurr.m) != 0 {
t.Fatalf("unexpected length of hm.m; got %d; want %d", len(hmCurr.m), 0)
}
if !hmCurr.isFull {
t.Fatalf("unexpected hmCurr.isFull; got %v; want %v", hmCurr.isFull, true)
}
hmPrev := s.prevHourMetricIDs.Load().(*hourMetricIDs)
if !reflect.DeepEqual(hmPrev, hmOrig) {
t.Fatalf("unexpected hmPrev; got %v; want %v", hmPrev, hmOrig)
}
if len(s.pendingHourMetricIDs) != 0 {
t.Fatalf("unexpected len(s.pendingHourMetricIDs); got %d; want %d", len(s.pendingHourMetricIDs), 0)
}
})
t.Run("empty_pedning_metric_ids_valid_curr_hour", func(t *testing.T) {
s := newStorage()
hour := uint64(timestampFromTime(time.Now())) / msecPerHour
hmOrig := &hourMetricIDs{
m: map[uint64]struct{}{
12: {},
34: {},
},
hour: hour,
}
s.currHourMetricIDs.Store(hmOrig)
s.updateCurrHourMetricIDs()
hmCurr := s.currHourMetricIDs.Load().(*hourMetricIDs)
if hmCurr.hour != hour {
// It is possible new hour occured. Update the hour and verify it again.
hour = uint64(timestampFromTime(time.Now())) / msecPerHour
if hmCurr.hour != hour {
t.Fatalf("unexpected hmCurr.hour; got %d; want %d", hmCurr.hour, hour)
}
// Do not run other checks, since they may fail.
return
}
if !reflect.DeepEqual(hmCurr, hmOrig) {
t.Fatalf("unexpected hmCurr; got %v; want %v", hmCurr, hmOrig)
}
if hmCurr.isFull {
t.Fatalf("unexpected hmCurr.isFull; got %v; want %v", hmCurr.isFull, false)
}
hmPrev := s.prevHourMetricIDs.Load().(*hourMetricIDs)
hmEmpty := &hourMetricIDs{}
if !reflect.DeepEqual(hmPrev, hmEmpty) {
t.Fatalf("unexpected hmPrev; got %v; want %v", hmPrev, hmEmpty)
}
if len(s.pendingHourMetricIDs) != 0 {
t.Fatalf("unexpected len(s.pendingHourMetricIDs); got %d; want %d", len(s.pendingHourMetricIDs), 0)
}
})
t.Run("nonempty_pending_metric_ids_stale_curr_hour", func(t *testing.T) {
s := newStorage()
pendingHourMetricIDs := map[uint64]struct{}{
343: {},
32424: {},
8293432: {},
}
s.pendingHourMetricIDs = pendingHourMetricIDs
hour := uint64(timestampFromTime(time.Now())) / msecPerHour
hmOrig := &hourMetricIDs{
m: map[uint64]struct{}{
12: {},
34: {},
},
hour: 123,
}
s.currHourMetricIDs.Store(hmOrig)
s.updateCurrHourMetricIDs()
hmCurr := s.currHourMetricIDs.Load().(*hourMetricIDs)
if hmCurr.hour != hour {
// It is possible new hour occured. Update the hour and verify it again.
hour = uint64(timestampFromTime(time.Now())) / msecPerHour
if hmCurr.hour != hour {
t.Fatalf("unexpected hmCurr.hour; got %d; want %d", hmCurr.hour, hour)
}
}
if !reflect.DeepEqual(hmCurr.m, pendingHourMetricIDs) {
t.Fatalf("unexpected hm.m; got %v; want %v", hmCurr.m, pendingHourMetricIDs)
}
if !hmCurr.isFull {
t.Fatalf("unexpected hmCurr.isFull; got %v; want %v", hmCurr.isFull, true)
}
hmPrev := s.prevHourMetricIDs.Load().(*hourMetricIDs)
if !reflect.DeepEqual(hmPrev, hmOrig) {
t.Fatalf("unexpected hmPrev; got %v; want %v", hmPrev, hmOrig)
}
if len(s.pendingHourMetricIDs) != 0 {
t.Fatalf("unexpected len(s.pendingHourMetricIDs); got %d; want %d", len(s.pendingHourMetricIDs), 0)
}
})
t.Run("nonempty_pending_metric_ids_valid_curr_hour", func(t *testing.T) {
s := newStorage()
pendingHourMetricIDs := map[uint64]struct{}{
343: {},
32424: {},
8293432: {},
}
s.pendingHourMetricIDs = pendingHourMetricIDs
hour := uint64(timestampFromTime(time.Now())) / msecPerHour
hmOrig := &hourMetricIDs{
m: map[uint64]struct{}{
12: {},
34: {},
},
hour: hour,
}
s.currHourMetricIDs.Store(hmOrig)
s.updateCurrHourMetricIDs()
hmCurr := s.currHourMetricIDs.Load().(*hourMetricIDs)
if hmCurr.hour != hour {
// It is possible new hour occured. Update the hour and verify it again.
hour = uint64(timestampFromTime(time.Now())) / msecPerHour
if hmCurr.hour != hour {
t.Fatalf("unexpected hmCurr.hour; got %d; want %d", hmCurr.hour, hour)
}
// Do not run other checks, since they may fail.
return
}
m := getMetricIDsCopy(pendingHourMetricIDs)
for metricID := range hmOrig.m {
m[metricID] = struct{}{}
}
if !reflect.DeepEqual(hmCurr.m, m) {
t.Fatalf("unexpected hm.m; got %v; want %v", hmCurr.m, m)
}
if hmCurr.isFull {
t.Fatalf("unexpected hmCurr.isFull; got %v; want %v", hmCurr.isFull, false)
}
hmPrev := s.prevHourMetricIDs.Load().(*hourMetricIDs)
hmEmpty := &hourMetricIDs{}
if !reflect.DeepEqual(hmPrev, hmEmpty) {
t.Fatalf("unexpected hmPrev; got %v; want %v", hmPrev, hmEmpty)
}
if len(s.pendingHourMetricIDs) != 0 {
t.Fatalf("unexpected len(s.pendingHourMetricIDs); got %d; want %d", len(s.pendingHourMetricIDs), 0)
}
})
}
func TestMetricRowMarshalUnmarshal(t *testing.T) {
var buf []byte
typ := reflect.TypeOf(&MetricRow{})

View File

@@ -164,10 +164,10 @@ func (tb *table) CreateSnapshot(snapshotName string) (string, string, error) {
}
}
fs.SyncPath(dstSmallDir)
fs.SyncPath(dstBigDir)
fs.SyncPath(filepath.Dir(dstSmallDir))
fs.SyncPath(filepath.Dir(dstBigDir))
fs.MustSyncPath(dstSmallDir)
fs.MustSyncPath(dstBigDir)
fs.MustSyncPath(filepath.Dir(dstSmallDir))
fs.MustSyncPath(filepath.Dir(dstBigDir))
logger.Infof("created table snapshot for %q at (%q, %q) in %s", tb.path, dstSmallDir, dstBigDir, time.Since(startTime))
return dstSmallDir, dstBigDir, nil
@@ -176,9 +176,9 @@ func (tb *table) CreateSnapshot(snapshotName string) (string, string, error) {
// MustDeleteSnapshot deletes snapshot with the given snapshotName.
func (tb *table) MustDeleteSnapshot(snapshotName string) {
smallDir := fmt.Sprintf("%s/small/snapshots/%s", tb.path, snapshotName)
fs.MustRemoveAllSynced(smallDir)
fs.MustRemoveAll(smallDir)
bigDir := fmt.Sprintf("%s/big/snapshots/%s", tb.path, snapshotName)
fs.MustRemoveAllSynced(bigDir)
fs.MustRemoveAll(bigDir)
}
func (tb *table) addPartitionNolock(pt *partition) {

View File

@@ -81,6 +81,13 @@ func (tfs *TagFilters) Reset() {
tfs.commonPrefix = marshalCommonPrefix(tfs.commonPrefix[:0], nsPrefixTagToMetricID)
}
func (tfs *TagFilters) marshal(dst []byte) []byte {
for i := range tfs.tfs {
dst = tfs.tfs[i].Marshal(dst)
}
return dst
}
// tagFilter represents a filter used for filtering tags.
type tagFilter struct {
key []byte

View File

@@ -67,3 +67,5 @@ func (tr *TimeRange) fromPartitionTime(t time.Time) {
}
const msecPerDay = 24 * 3600 * 1000
const msecPerHour = 3600 * 1000

View File

@@ -0,0 +1,38 @@
package timerpool
import (
"sync"
"time"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
)
// Get returns a timer for the given duration d from the pool.
//
// Return back the timer to the pool with Put.
func Get(d time.Duration) *time.Timer {
if v := timerPool.Get(); v != nil {
t := v.(*time.Timer)
if t.Reset(d) {
logger.Panicf("BUG: active timer trapped to the pool!")
}
return t
}
return time.NewTimer(d)
}
// Put returns t to the pool.
//
// t cannot be accessed after returning to the pool.
func Put(t *time.Timer) {
if !t.Stop() {
// Drain t.C if it wasn't obtained by the caller yet.
select {
case <-t.C:
default:
}
}
timerPool.Put(t)
}
var timerPool sync.Pool

View File

@@ -17,6 +17,10 @@ const chunkSize = 64 * 1024
const bucketSizeBits = 40
const genSizeBits = 64 - bucketSizeBits
const maxGen = 1<<genSizeBits - 1
const maxBucketSize uint64 = 1 << bucketSizeBits
// Stats represents cache stats.
@@ -254,13 +258,13 @@ func (b *bucket) Reset() {
func (b *bucket) Clean() {
b.mu.Lock()
bGen := b.gen
bGen := b.gen & ((1 << genSizeBits) - 1)
bIdx := b.idx
bm := b.m
for k, v := range bm {
gen := v >> bucketSizeBits
idx := v & ((1 << bucketSizeBits) - 1)
if gen == bGen && idx < bIdx || gen+1 == bGen && idx >= bIdx {
if gen == bGen && idx < bIdx || gen+1 == bGen && idx >= bIdx || gen == maxGen && bGen == 1 && idx >= bIdx {
continue
}
delete(bm, k)
@@ -317,8 +321,8 @@ func (b *bucket) Set(k, v []byte, h uint64) {
idxNew = kvLen
chunkIdx = 0
b.gen++
if b.gen == 0 {
b.gen = 1
if b.gen&((1<<genSizeBits)-1) == 0 {
b.gen++
}
} else {
idx = chunkIdxNew * chunkSize
@@ -346,10 +350,11 @@ func (b *bucket) Get(dst, k []byte, h uint64, returnDst bool) ([]byte, bool) {
found := false
b.mu.RLock()
v := b.m[h]
bGen := b.gen & ((1 << genSizeBits) - 1)
if v > 0 {
gen := v >> bucketSizeBits
idx := v & ((1 << bucketSizeBits) - 1)
if gen == b.gen && idx < b.idx || gen+1 == b.gen && idx >= b.idx {
if gen == bGen && idx < b.idx || gen+1 == bGen && idx >= b.idx || gen == maxGen && bGen == 1 && idx >= b.idx {
chunkIdx := idx / chunkSize
if chunkIdx >= uint64(len(b.chunks)) {
// Corrupted data during the load from file. Just skip it.

View File

@@ -17,9 +17,7 @@ import (
//
// The returned counter is safe to use from concurrent goroutines.
func NewCounter(name string) *Counter {
c := &Counter{}
registerMetric(name, c)
return c
return defaultSet.NewCounter(name)
}
// Counter is a counter.
@@ -75,30 +73,5 @@ func (c *Counter) marshalTo(prefix string, w io.Writer) {
//
// Performance tip: prefer NewCounter instead of GetOrCreateCounter.
func GetOrCreateCounter(name string) *Counter {
metricsMapLock.Lock()
nm := metricsMap[name]
metricsMapLock.Unlock()
if nm == nil {
// Slow path - create and register missing counter.
if err := validateMetric(name); err != nil {
panic(fmt.Errorf("BUG: invalid metric name %q: %s", name, err))
}
nmNew := &namedMetric{
name: name,
metric: &Counter{},
}
metricsMapLock.Lock()
nm = metricsMap[name]
if nm == nil {
nm = nmNew
metricsMap[name] = nm
metricsList = append(metricsList, nm)
}
metricsMapLock.Unlock()
}
c, ok := nm.metric.(*Counter)
if !ok {
panic(fmt.Errorf("BUG: metric %q isn't a Counter. It is %T", name, nm.metric))
}
return c
return defaultSet.GetOrCreateCounter(name)
}

View File

@@ -19,14 +19,7 @@ import (
//
// The returned gauge is safe to use from concurrent goroutines.
func NewGauge(name string, f func() float64) *Gauge {
if f == nil {
panic(fmt.Errorf("BUG: f cannot be nil"))
}
g := &Gauge{
f: f,
}
registerMetric(name, g)
return g
return defaultSet.NewGauge(name, f)
}
// Gauge is a float64 gauge.
@@ -66,35 +59,5 @@ func (g *Gauge) marshalTo(prefix string, w io.Writer) {
//
// Performance tip: prefer NewGauge instead of GetOrCreateGauge.
func GetOrCreateGauge(name string, f func() float64) *Gauge {
metricsMapLock.Lock()
nm := metricsMap[name]
metricsMapLock.Unlock()
if nm == nil {
// Slow path - create and register missing gauge.
if f == nil {
panic(fmt.Errorf("BUG: f cannot be nil"))
}
if err := validateMetric(name); err != nil {
panic(fmt.Errorf("BUG: invalid metric name %q: %s", name, err))
}
nmNew := &namedMetric{
name: name,
metric: &Gauge{
f: f,
},
}
metricsMapLock.Lock()
nm = metricsMap[name]
if nm == nil {
nm = nmNew
metricsMap[name] = nm
metricsList = append(metricsList, nm)
}
metricsMapLock.Unlock()
}
g, ok := nm.metric.(*Gauge)
if !ok {
panic(fmt.Errorf("BUG: metric %q isn't a Gauge. It is %T", name, nm.metric))
}
return g
return defaultSet.GetOrCreateGauge(name, f)
}

View File

@@ -8,25 +8,18 @@
// 1. Register the required metrics via New* functions.
// 2. Expose them to `/metrics` page via WritePrometheus.
// 3. Update the registered metrics during application lifetime.
//
// The package has been extracted from https://victoriametrics.com/
package metrics
import (
"fmt"
"io"
"runtime"
"sort"
"sync"
"time"
"github.com/valyala/histogram"
)
var (
metricsMapLock sync.Mutex
metricsList []*namedMetric
metricsMap = make(map[string]*namedMetric)
)
type namedMetric struct {
name string
metric metric
@@ -36,6 +29,8 @@ type metric interface {
marshalTo(prefix string, w io.Writer)
}
var defaultSet = NewSet()
// WritePrometheus writes all the registered metrics in Prometheus format to w.
//
// If exposeProcessMetrics is true, then various `go_*` metrics are exposed
@@ -48,17 +43,7 @@ type metric interface {
// })
//
func WritePrometheus(w io.Writer, exposeProcessMetrics bool) {
lessFunc := func(i, j int) bool {
return metricsList[i].name < metricsList[j].name
}
metricsMapLock.Lock()
if !sort.SliceIsSorted(metricsList, lessFunc) {
sort.Slice(metricsList, lessFunc)
}
for _, nm := range metricsList {
nm.metric.marshalTo(nm.name, w)
}
metricsMapLock.Unlock()
defaultSet.WritePrometheus(w)
if exposeProcessMetrics {
writeProcessMetrics(w)
}
@@ -118,25 +103,3 @@ func writeProcessMetrics(w io.Writer) {
fmt.Fprintf(w, "go_info_ext{compiler=%q, GOARCH=%q, GOOS=%q, GOROOT=%q} 1\n",
runtime.Compiler, runtime.GOARCH, runtime.GOOS, runtime.GOROOT())
}
var startTime = time.Now()
func registerMetric(name string, m metric) {
if err := validateMetric(name); err != nil {
panic(fmt.Errorf("BUG: invalid metric name %q: %s", name, err))
}
metricsMapLock.Lock()
nm, ok := metricsMap[name]
if !ok {
nm = &namedMetric{
name: name,
metric: m,
}
metricsMap[name] = nm
metricsList = append(metricsList, nm)
}
metricsMapLock.Unlock()
if ok {
panic(fmt.Errorf("BUG: metric %q is already registered", name))
}
}

308
vendor/github.com/VictoriaMetrics/metrics/set.go generated vendored Normal file
View File

@@ -0,0 +1,308 @@
package metrics
import (
"fmt"
"io"
"sort"
"sync"
"time"
)
// Set is a set of metrics.
//
// Metrics belonging to a set are exported separately from global metrics.
//
// Set.WritePrometheus must be called for exporting metrics from the set.
type Set struct {
mu sync.Mutex
a []*namedMetric
m map[string]*namedMetric
}
// NewSet creates new set of metrics.
func NewSet() *Set {
return &Set{
m: make(map[string]*namedMetric),
}
}
// WritePrometheus writes all the metrics from s to w in Prometheus format.
func (s *Set) WritePrometheus(w io.Writer) {
lessFunc := func(i, j int) bool {
return s.a[i].name < s.a[j].name
}
s.mu.Lock()
if !sort.SliceIsSorted(s.a, lessFunc) {
sort.Slice(s.a, lessFunc)
}
for _, nm := range s.a {
nm.metric.marshalTo(nm.name, w)
}
s.mu.Unlock()
}
// NewCounter registers and returns new counter with the given name in the s.
//
// name must be valid Prometheus-compatible metric with possible lables.
// For instance,
//
// * foo
// * foo{bar="baz"}
// * foo{bar="baz",aaa="b"}
//
// The returned counter is safe to use from concurrent goroutines.
func (s *Set) NewCounter(name string) *Counter {
c := &Counter{}
s.registerMetric(name, c)
return c
}
// GetOrCreateCounter returns registered counter in s with the given name
// or creates new counter if s doesn't contain counter with the given name.
//
// name must be valid Prometheus-compatible metric with possible lables.
// For instance,
//
// * foo
// * foo{bar="baz"}
// * foo{bar="baz",aaa="b"}
//
// The returned counter is safe to use from concurrent goroutines.
//
// Performance tip: prefer NewCounter instead of GetOrCreateCounter.
func (s *Set) GetOrCreateCounter(name string) *Counter {
s.mu.Lock()
nm := s.m[name]
s.mu.Unlock()
if nm == nil {
// Slow path - create and register missing counter.
if err := validateMetric(name); err != nil {
panic(fmt.Errorf("BUG: invalid metric name %q: %s", name, err))
}
nmNew := &namedMetric{
name: name,
metric: &Counter{},
}
s.mu.Lock()
nm = s.m[name]
if nm == nil {
nm = nmNew
s.m[name] = nm
s.a = append(s.a, nm)
}
s.mu.Unlock()
}
c, ok := nm.metric.(*Counter)
if !ok {
panic(fmt.Errorf("BUG: metric %q isn't a Counter. It is %T", name, nm.metric))
}
return c
}
// NewGauge registers and returns gauge with the given name in s, which calls f
// to obtain gauge value.
//
// name must be valid Prometheus-compatible metric with possible labels.
// For instance,
//
// * foo
// * foo{bar="baz"}
// * foo{bar="baz",aaa="b"}
//
// f must be safe for concurrent calls.
//
// The returned gauge is safe to use from concurrent goroutines.
func (s *Set) NewGauge(name string, f func() float64) *Gauge {
if f == nil {
panic(fmt.Errorf("BUG: f cannot be nil"))
}
g := &Gauge{
f: f,
}
s.registerMetric(name, g)
return g
}
// GetOrCreateGauge returns registered gauge with the given name in s
// or creates new gauge if s doesn't contain gauge with the given name.
//
// name must be valid Prometheus-compatible metric with possible lables.
// For instance,
//
// * foo
// * foo{bar="baz"}
// * foo{bar="baz",aaa="b"}
//
// The returned gauge is safe to use from concurrent goroutines.
//
// Performance tip: prefer NewGauge instead of GetOrCreateGauge.
func (s *Set) GetOrCreateGauge(name string, f func() float64) *Gauge {
s.mu.Lock()
nm := s.m[name]
s.mu.Unlock()
if nm == nil {
// Slow path - create and register missing gauge.
if f == nil {
panic(fmt.Errorf("BUG: f cannot be nil"))
}
if err := validateMetric(name); err != nil {
panic(fmt.Errorf("BUG: invalid metric name %q: %s", name, err))
}
nmNew := &namedMetric{
name: name,
metric: &Gauge{
f: f,
},
}
s.mu.Lock()
nm = s.m[name]
if nm == nil {
nm = nmNew
s.m[name] = nm
s.a = append(s.a, nm)
}
s.mu.Unlock()
}
g, ok := nm.metric.(*Gauge)
if !ok {
panic(fmt.Errorf("BUG: metric %q isn't a Gauge. It is %T", name, nm.metric))
}
return g
}
// NewSummary creates and returns new summary with the given name in s.
//
// name must be valid Prometheus-compatible metric with possible lables.
// For instance,
//
// * foo
// * foo{bar="baz"}
// * foo{bar="baz",aaa="b"}
//
// The returned summary is safe to use from concurrent goroutines.
func (s *Set) NewSummary(name string) *Summary {
return s.NewSummaryExt(name, defaultSummaryWindow, defaultSummaryQuantiles)
}
// NewSummaryExt creates and returns new summary in s with the given name,
// window and quantiles.
//
// name must be valid Prometheus-compatible metric with possible lables.
// For instance,
//
// * foo
// * foo{bar="baz"}
// * foo{bar="baz",aaa="b"}
//
// The returned summary is safe to use from concurrent goroutines.
func (s *Set) NewSummaryExt(name string, window time.Duration, quantiles []float64) *Summary {
sm := newSummary(window, quantiles)
s.registerMetric(name, sm)
registerSummary(sm)
s.registerSummaryQuantiles(name, sm)
return sm
}
// GetOrCreateSummary returns registered summary with the given name in s
// or creates new summary if s doesn't contain summary with the given name.
//
// name must be valid Prometheus-compatible metric with possible lables.
// For instance,
//
// * foo
// * foo{bar="baz"}
// * foo{bar="baz",aaa="b"}
//
// The returned summary is safe to use from concurrent goroutines.
//
// Performance tip: prefer NewSummary instead of GetOrCreateSummary.
func (s *Set) GetOrCreateSummary(name string) *Summary {
return s.GetOrCreateSummaryExt(name, defaultSummaryWindow, defaultSummaryQuantiles)
}
// GetOrCreateSummaryExt returns registered summary with the given name,
// window and quantiles in s or creates new summary if s doesn't
// contain summary with the given name.
//
// name must be valid Prometheus-compatible metric with possible lables.
// For instance,
//
// * foo
// * foo{bar="baz"}
// * foo{bar="baz",aaa="b"}
//
// The returned summary is safe to use from concurrent goroutines.
//
// Performance tip: prefer NewSummaryExt instead of GetOrCreateSummaryExt.
func (s *Set) GetOrCreateSummaryExt(name string, window time.Duration, quantiles []float64) *Summary {
s.mu.Lock()
nm := s.m[name]
s.mu.Unlock()
if nm == nil {
// Slow path - create and register missing summary.
if err := validateMetric(name); err != nil {
panic(fmt.Errorf("BUG: invalid metric name %q: %s", name, err))
}
sm := newSummary(window, quantiles)
nmNew := &namedMetric{
name: name,
metric: sm,
}
mustRegisterQuantiles := false
s.mu.Lock()
nm = s.m[name]
if nm == nil {
nm = nmNew
s.m[name] = nm
s.a = append(s.a, nm)
registerSummary(sm)
mustRegisterQuantiles = true
}
s.mu.Unlock()
if mustRegisterQuantiles {
s.registerSummaryQuantiles(name, sm)
}
}
sm, ok := nm.metric.(*Summary)
if !ok {
panic(fmt.Errorf("BUG: metric %q isn't a Summary. It is %T", name, nm.metric))
}
if sm.window != window {
panic(fmt.Errorf("BUG: invalid window requested for the summary %q; requested %s; need %s", name, window, sm.window))
}
if !isEqualQuantiles(sm.quantiles, quantiles) {
panic(fmt.Errorf("BUG: invalid quantiles requested from the summary %q; requested %v; need %v", name, quantiles, sm.quantiles))
}
return sm
}
func (s *Set) registerSummaryQuantiles(name string, sm *Summary) {
for i, q := range sm.quantiles {
quantileValueName := addTag(name, fmt.Sprintf(`quantile="%g"`, q))
qv := &quantileValue{
sm: sm,
idx: i,
}
s.registerMetric(quantileValueName, qv)
}
}
func (s *Set) registerMetric(name string, m metric) {
if err := validateMetric(name); err != nil {
panic(fmt.Errorf("BUG: invalid metric name %q: %s", name, err))
}
s.mu.Lock()
nm, ok := s.m[name]
if !ok {
nm = &namedMetric{
name: name,
metric: m,
}
s.m[name] = nm
s.a = append(s.a, nm)
}
s.mu.Unlock()
if ok {
panic(fmt.Errorf("BUG: metric %q is already registered", name))
}
}

View File

@@ -38,7 +38,7 @@ type Summary struct {
//
// The returned summary is safe to use from concurrent goroutines.
func NewSummary(name string) *Summary {
return NewSummaryExt(name, defaultSummaryWindow, defaultSummaryQuantiles)
return defaultSet.NewSummary(name)
}
// NewSummaryExt creates and returns new summary with the given name,
@@ -53,36 +53,21 @@ func NewSummary(name string) *Summary {
//
// The returned summary is safe to use from concurrent goroutines.
func NewSummaryExt(name string, window time.Duration, quantiles []float64) *Summary {
s := newSummary(window, quantiles)
registerMetric(name, s)
registerSummary(s)
registerSummaryQuantiles(name, s)
return s
return defaultSet.NewSummaryExt(name, window, quantiles)
}
func newSummary(window time.Duration, quantiles []float64) *Summary {
// Make a copy of quantiles in order to prevent from their modification by the caller.
quantiles = append([]float64{}, quantiles...)
validateQuantiles(quantiles)
s := &Summary{
sm := &Summary{
curr: histogram.NewFast(),
next: histogram.NewFast(),
quantiles: quantiles,
quantileValues: make([]float64, len(quantiles)),
window: window,
}
return s
}
func registerSummaryQuantiles(name string, s *Summary) {
for i, q := range s.quantiles {
quantileValueName := addTag(name, fmt.Sprintf(`quantile="%g"`, q))
qv := &quantileValue{
s: s,
idx: i,
}
registerMetric(quantileValueName, qv)
}
return sm
}
func validateQuantiles(quantiles []float64) {
@@ -94,29 +79,29 @@ func validateQuantiles(quantiles []float64) {
}
// Update updates the summary.
func (s *Summary) Update(v float64) {
s.mu.Lock()
s.curr.Update(v)
s.next.Update(v)
s.mu.Unlock()
func (sm *Summary) Update(v float64) {
sm.mu.Lock()
sm.curr.Update(v)
sm.next.Update(v)
sm.mu.Unlock()
}
// UpdateDuration updates request duration based on the given startTime.
func (s *Summary) UpdateDuration(startTime time.Time) {
func (sm *Summary) UpdateDuration(startTime time.Time) {
d := time.Since(startTime).Seconds()
s.Update(d)
sm.Update(d)
}
func (s *Summary) marshalTo(prefix string, w io.Writer) {
// Just update s.quantileValues and don't write anything to w.
// s.quantileValues will be marshaled later via quantileValue.marshalTo.
s.updateQuantiles()
func (sm *Summary) marshalTo(prefix string, w io.Writer) {
// Just update sm.quantileValues and don't write anything to w.
// sm.quantileValues will be marshaled later via quantileValue.marshalTo.
sm.updateQuantiles()
}
func (s *Summary) updateQuantiles() {
s.mu.Lock()
s.quantileValues = s.curr.Quantiles(s.quantileValues[:0], s.quantiles)
s.mu.Unlock()
func (sm *Summary) updateQuantiles() {
sm.mu.Lock()
sm.quantileValues = sm.curr.Quantiles(sm.quantileValues[:0], sm.quantiles)
sm.mu.Unlock()
}
// GetOrCreateSummary returns registered summary with the given name
@@ -134,7 +119,7 @@ func (s *Summary) updateQuantiles() {
//
// Performance tip: prefer NewSummary instead of GetOrCreateSummary.
func GetOrCreateSummary(name string) *Summary {
return GetOrCreateSummaryExt(name, defaultSummaryWindow, defaultSummaryQuantiles)
return defaultSet.GetOrCreateSummary(name)
}
// GetOrCreateSummaryExt returns registered summary with the given name,
@@ -152,45 +137,7 @@ func GetOrCreateSummary(name string) *Summary {
//
// Performance tip: prefer NewSummaryExt instead of GetOrCreateSummaryExt.
func GetOrCreateSummaryExt(name string, window time.Duration, quantiles []float64) *Summary {
metricsMapLock.Lock()
nm := metricsMap[name]
metricsMapLock.Unlock()
if nm == nil {
// Slow path - create and register missing summary.
if err := validateMetric(name); err != nil {
panic(fmt.Errorf("BUG: invalid metric name %q: %s", name, err))
}
s := newSummary(window, quantiles)
nmNew := &namedMetric{
name: name,
metric: s,
}
mustRegisterQuantiles := false
metricsMapLock.Lock()
nm = metricsMap[name]
if nm == nil {
nm = nmNew
metricsMap[name] = nm
metricsList = append(metricsList, nm)
registerSummary(s)
mustRegisterQuantiles = true
}
metricsMapLock.Unlock()
if mustRegisterQuantiles {
registerSummaryQuantiles(name, s)
}
}
s, ok := nm.metric.(*Summary)
if !ok {
panic(fmt.Errorf("BUG: metric %q isn't a Summary. It is %T", name, nm.metric))
}
if s.window != window {
panic(fmt.Errorf("BUG: invalid window requested for the summary %q; requested %s; need %s", name, window, s.window))
}
if !isEqualQuantiles(s.quantiles, quantiles) {
panic(fmt.Errorf("BUG: invalid quantiles requested from the summary %q; requested %v; need %v", name, quantiles, s.quantiles))
}
return s
return defaultSet.GetOrCreateSummaryExt(name, window, quantiles)
}
func isEqualQuantiles(a, b []float64) bool {
@@ -207,14 +154,14 @@ func isEqualQuantiles(a, b []float64) bool {
}
type quantileValue struct {
s *Summary
sm *Summary
idx int
}
func (qv *quantileValue) marshalTo(prefix string, w io.Writer) {
qv.s.mu.Lock()
v := qv.s.quantileValues[qv.idx]
qv.s.mu.Unlock()
qv.sm.mu.Lock()
v := qv.sm.quantileValues[qv.idx]
qv.sm.mu.Unlock()
if !math.IsNaN(v) {
fmt.Fprintf(w, "%s %g\n", prefix, v)
}
@@ -227,10 +174,10 @@ func addTag(name, tag string) string {
return fmt.Sprintf("%s,%s}", name[:len(name)-1], tag)
}
func registerSummary(s *Summary) {
window := s.window
func registerSummary(sm *Summary) {
window := sm.window
summariesLock.Lock()
summaries[window] = append(summaries[window], s)
summaries[window] = append(summaries[window], sm)
if len(summaries[window]) == 1 {
go summariesSwapCron(window)
}
@@ -241,13 +188,13 @@ func summariesSwapCron(window time.Duration) {
for {
time.Sleep(window / 2)
summariesLock.Lock()
for _, s := range summaries[window] {
s.mu.Lock()
tmp := s.curr
s.curr = s.next
s.next = tmp
s.next.Reset()
s.mu.Unlock()
for _, sm := range summaries[window] {
sm.mu.Lock()
tmp := sm.curr
sm.curr = sm.next
sm.next = tmp
sm.next.Reset()
sm.mu.Unlock()
}
summariesLock.Unlock()
}

54
vendor/golang.org/x/sys/unix/asm_linux_riscv64.s generated vendored Normal file
View File

@@ -0,0 +1,54 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build riscv64,!gccgo
#include "textflag.h"
//
// System calls for linux/riscv64.
//
// Where available, just jump to package syscall's implementation of
// these functions.
TEXT ·Syscall(SB),NOSPLIT,$0-56
JMP syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-80
JMP syscall·Syscall6(SB)
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
CALL runtime·entersyscall(SB)
MOV a1+8(FP), A0
MOV a2+16(FP), A1
MOV a3+24(FP), A2
MOV $0, A3
MOV $0, A4
MOV $0, A5
MOV $0, A6
MOV trap+0(FP), A7 // syscall entry
ECALL
MOV A0, r1+32(FP) // r1
MOV A1, r2+40(FP) // r2
CALL runtime·exitsyscall(SB)
RET
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
JMP syscall·RawSyscall6(SB)
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
MOV a1+8(FP), A0
MOV a2+16(FP), A1
MOV a3+24(FP), A2
MOV ZERO, A3
MOV ZERO, A4
MOV ZERO, A5
MOV trap+0(FP), A7 // syscall entry
ECALL
MOV A0, r1+32(FP)
MOV A1, r2+40(FP)
RET

View File

@@ -182,6 +182,7 @@ struct ltchars {
#include <sys/signalfd.h>
#include <sys/socket.h>
#include <sys/xattr.h>
#include <linux/bpf.h>
#include <linux/errqueue.h>
#include <linux/if.h>
#include <linux/if_alg.h>
@@ -433,7 +434,7 @@ ccflags="$@"
$2 ~ /^TC[IO](ON|OFF)$/ ||
$2 ~ /^IN_/ ||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|MCAST|EVFILT|NOTE|EV|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
$2 ~ /^TP_STATUS_/ ||
$2 ~ /^FALLOC_/ ||
$2 == "ICMPV6_FILTER" ||
@@ -466,7 +467,7 @@ ccflags="$@"
$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|LOCKS|MEMLOCK|MSGQUEUE|NICE|NOFILE|NPROC|RSS|RTPRIO|RTTIME|SIGPENDING|STACK)|RLIM_INFINITY/ ||
$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
$2 ~ /^CLONE_[A-Z_]+/ ||
$2 !~ /^(BPF_TIMEVAL)$/ &&
$2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ &&
$2 ~ /^(BPF|DLT)_/ ||
$2 ~ /^(CLOCK|TIMER)_/ ||
$2 ~ /^CAN_/ ||

View File

@@ -454,8 +454,8 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
//sys Dup2(oldfd int, newfd int) (err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = posix_fadvise64
//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) = fstatat
//sys fstat(fd int, stat *Stat_t) (err error)
//sys fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = fstatat
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int)
@@ -464,7 +464,7 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
//sysnb Getuid() (uid int)
//sys Lchown(path string, uid int, gid int) (err error)
//sys Listen(s int, n int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error)
//sys lstat(path string, stat *Stat_t) (err error)
//sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = pread64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64
@@ -474,7 +474,7 @@ func IoctlGetTermios(fd int, req uint) (*Termios, 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)
//sys Stat(path string, stat *Stat_t) (err error)
//sys stat(path string, statptr *Stat_t) (err error)
//sys Statfs(path string, buf *Statfs_t) (err error)
//sys Truncate(path string, length int64) (err error)

View File

@@ -32,3 +32,19 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
func Fstat(fd int, stat *Stat_t) error {
return fstat(fd, stat)
}
func Fstatat(dirfd int, path string, stat *Stat_t, flags int) error {
return fstatat(dirfd, path, stat, flags)
}
func Lstat(path string, stat *Stat_t) error {
return lstat(path, stat)
}
func Stat(path string, statptr *Stat_t) error {
return stat(path, statptr)
}

View File

@@ -32,3 +32,50 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
// In order to only have Timespec structure, type of Stat_t's fields
// Atim, Mtim and Ctim is changed from StTimespec to Timespec during
// ztypes generation.
// On ppc64, Timespec.Nsec is an int64 while StTimespec.Nsec is an
// int32, so the fields' value must be modified.
func fixStatTimFields(stat *Stat_t) {
stat.Atim.Nsec >>= 32
stat.Mtim.Nsec >>= 32
stat.Ctim.Nsec >>= 32
}
func Fstat(fd int, stat *Stat_t) error {
err := fstat(fd, stat)
if err != nil {
return err
}
fixStatTimFields(stat)
return nil
}
func Fstatat(dirfd int, path string, stat *Stat_t, flags int) error {
err := fstatat(dirfd, path, stat, flags)
if err != nil {
return err
}
fixStatTimFields(stat)
return nil
}
func Lstat(path string, stat *Stat_t) error {
err := lstat(path, stat)
if err != nil {
return err
}
fixStatTimFields(stat)
return nil
}
func Stat(path string, statptr *Stat_t) error {
err := stat(path, statptr)
if err != nil {
return err
}
fixStatTimFields(statptr)
return nil
}

View File

@@ -404,22 +404,22 @@ func roundup(x, y int) int {
func (s *Stat_t) convertFrom(old *stat_freebsd11_t) {
*s = Stat_t{
Dev: uint64(old.Dev),
Ino: uint64(old.Ino),
Nlink: uint64(old.Nlink),
Mode: old.Mode,
Uid: old.Uid,
Gid: old.Gid,
Rdev: uint64(old.Rdev),
Atim: old.Atim,
Mtim: old.Mtim,
Ctim: old.Ctim,
Birthtim: old.Birthtim,
Size: old.Size,
Blocks: old.Blocks,
Blksize: old.Blksize,
Flags: old.Flags,
Gen: uint64(old.Gen),
Dev: uint64(old.Dev),
Ino: uint64(old.Ino),
Nlink: uint64(old.Nlink),
Mode: old.Mode,
Uid: old.Uid,
Gid: old.Gid,
Rdev: uint64(old.Rdev),
Atim: old.Atim,
Mtim: old.Mtim,
Ctim: old.Ctim,
Btim: old.Btim,
Size: old.Size,
Blocks: old.Blocks,
Blksize: old.Blksize,
Flags: old.Flags,
Gen: uint64(old.Gen),
}
}

View File

@@ -109,6 +109,12 @@ func IoctlGetInt(fd int, req uint) (int, error) {
return value, err
}
func IoctlGetUint32(fd int, req uint) (uint32, error) {
var value uint32
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return value, err
}
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
var value Winsize
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
@@ -1531,9 +1537,13 @@ func Setgid(uid int) (err error) {
return EOPNOTSUPP
}
func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
return signalfd(fd, sigmask, _C__NSIG/8, flags)
}
//sys Setpriority(which int, who int, prio int) (err error)
//sys Setxattr(path string, attr string, data []byte, flags int) (err error)
//sys Signalfd(fd int, mask *Sigset_t, flags int) = SYS_SIGNALFD4
//sys signalfd(fd int, sigmask *Sigset_t, maskSize uintptr, flags int) (newfd int, err error) = SYS_SIGNALFD4
//sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error)
//sys Sync()
//sys Syncfs(fd int) (err error)

View File

@@ -272,3 +272,16 @@ func SyncFileRange(fd int, off int64, n int64, flags int) error {
// order of their arguments.
return armSyncFileRange(fd, flags, off, n)
}
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
cmdlineLen := len(cmdline)
if cmdlineLen > 0 {
// Account for the additional NULL byte added by
// BytePtrFromString in kexecFileLoad. The kexec_file_load
// syscall expects a NULL-terminated string.
cmdlineLen++
}
return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
}

View File

@@ -197,10 +197,59 @@ const (
BPF_ABS = 0x20
BPF_ADD = 0x0
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_FROM_BE = 0x8
BPF_FROM_LE = 0x0
BPF_FS_MAGIC = 0xcafe4a11
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
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_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_RECOMPUTE_CSUM = 0x1
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_TUNINFO_IPV6 = 0x1
BPF_F_USER_BUILD_ID = 0x800
BPF_F_USER_STACK = 0x100
BPF_F_WRONLY = 0x10
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_ZERO_SEED = 0x40
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -208,8 +257,16 @@ const (
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
BPF_JLE = 0xb0
BPF_JLT = 0xa0
BPF_JMP = 0x5
BPF_JMP32 = 0x6
BPF_JNE = 0x50
BPF_JSET = 0x40
BPF_JSGE = 0x70
BPF_JSGT = 0x60
BPF_JSLE = 0xd0
BPF_JSLT = 0xc0
BPF_K = 0x0
BPF_LD = 0x0
BPF_LDX = 0x1
@@ -223,20 +280,33 @@ const (
BPF_MINOR_VERSION = 0x1
BPF_MISC = 0x7
BPF_MOD = 0x90
BPF_MOV = 0xb0
BPF_MSH = 0xa0
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
BPF_PSEUDO_MAP_FD = 0x1
BPF_RET = 0x6
BPF_RSH = 0x70
BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7
BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2
BPF_SOCK_OPS_RTO_CB_FLAG = 0x1
BPF_SOCK_OPS_STATE_CB_FLAG = 0x4
BPF_ST = 0x2
BPF_STX = 0x3
BPF_SUB = 0x10
BPF_TAG_SIZE = 0x8
BPF_TAX = 0x0
BPF_TO_BE = 0x8
BPF_TO_LE = 0x0
BPF_TXA = 0x80
BPF_W = 0x0
BPF_X = 0x8
BPF_XADD = 0xc0
BPF_XOR = 0xa0
BRKINT = 0x2
BS0 = 0x0
@@ -501,6 +571,7 @@ const (
FAN_ALL_MARK_FLAGS = 0xff
FAN_ALL_OUTGOING_EVENTS = 0x3403b
FAN_ALL_PERM_EVENTS = 0x30000
FAN_ATTRIB = 0x4
FAN_AUDIT = 0x10
FAN_CLASS_CONTENT = 0x4
FAN_CLASS_NOTIF = 0x0
@@ -509,8 +580,12 @@ const (
FAN_CLOSE = 0x18
FAN_CLOSE_NOWRITE = 0x10
FAN_CLOSE_WRITE = 0x8
FAN_CREATE = 0x100
FAN_DELETE = 0x200
FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40
FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1
@@ -524,6 +599,10 @@ const (
FAN_MARK_ONLYDIR = 0x8
FAN_MARK_REMOVE = 0x2
FAN_MODIFY = 0x2
FAN_MOVE = 0xc0
FAN_MOVED_FROM = 0x40
FAN_MOVED_TO = 0x80
FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2
FAN_ONDIR = 0x40000000
@@ -532,6 +611,7 @@ const (
FAN_OPEN_EXEC_PERM = 0x40000
FAN_OPEN_PERM = 0x10000
FAN_Q_OVERFLOW = 0x4000
FAN_REPORT_FID = 0x200
FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
@@ -1056,6 +1136,15 @@ const (
MAP_STACK = 0x20000
MAP_SYNC = 0x80000
MAP_TYPE = 0xf
MCAST_BLOCK_SOURCE = 0x2b
MCAST_EXCLUDE = 0x0
MCAST_INCLUDE = 0x1
MCAST_JOIN_GROUP = 0x2a
MCAST_JOIN_SOURCE_GROUP = 0x2e
MCAST_LEAVE_GROUP = 0x2d
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
@@ -1491,6 +1580,7 @@ const (
PR_SET_TSC = 0x1a
PR_SET_UNALIGN = 0x6
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1
@@ -1961,6 +2051,7 @@ const (
SO_ATTACH_REUSEPORT_CBPF = 0x33
SO_ATTACH_REUSEPORT_EBPF = 0x34
SO_BINDTODEVICE = 0x19
SO_BINDTOIFINDEX = 0x3e
SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x6
SO_BSDCOMPAT = 0xe
@@ -2009,6 +2100,8 @@ const (
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x12
SO_RCVTIMEO = 0x14
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x14
SO_REUSEADDR = 0x2
SO_REUSEPORT = 0xf
SO_RXQ_OVFL = 0x28
@@ -2020,9 +2113,17 @@ const (
SO_SNDBUFFORCE = 0x20
SO_SNDLOWAT = 0x13
SO_SNDTIMEO = 0x15
SO_SNDTIMEO_NEW = 0x43
SO_SNDTIMEO_OLD = 0x15
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPING_NEW = 0x41
SO_TIMESTAMPING_OLD = 0x25
SO_TIMESTAMPNS = 0x23
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TIMESTAMP_OLD = 0x1d
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
@@ -2115,6 +2216,8 @@ 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
@@ -2316,8 +2419,10 @@ const (
UBI_IOCMKVOL = 0x40986f00
UBI_IOCRMVOL = 0x40046f01
UBI_IOCRNVOL = 0x51106f03
UBI_IOCRPEB = 0x40046f04
UBI_IOCRSVOL = 0x400c6f02
UBI_IOCSETVOLPROP = 0x40104f06
UBI_IOCSPEB = 0x40046f05
UBI_IOCVOLCRBLK = 0x40804f07
UBI_IOCVOLRMBLK = 0x4f08
UBI_IOCVOLUP = 0x40084f00
@@ -2466,6 +2571,7 @@ const (
XDP_FLAGS_SKB_MODE = 0x2
XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1
XDP_MMAP_OFFSETS = 0x1
XDP_PACKET_HEADROOM = 0x100
XDP_PGOFF_RX_RING = 0x0
XDP_PGOFF_TX_RING = 0x80000000
XDP_RX_RING = 0x2

View File

@@ -197,10 +197,59 @@ const (
BPF_ABS = 0x20
BPF_ADD = 0x0
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_FROM_BE = 0x8
BPF_FROM_LE = 0x0
BPF_FS_MAGIC = 0xcafe4a11
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
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_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_RECOMPUTE_CSUM = 0x1
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_TUNINFO_IPV6 = 0x1
BPF_F_USER_BUILD_ID = 0x800
BPF_F_USER_STACK = 0x100
BPF_F_WRONLY = 0x10
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_ZERO_SEED = 0x40
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -208,8 +257,16 @@ const (
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
BPF_JLE = 0xb0
BPF_JLT = 0xa0
BPF_JMP = 0x5
BPF_JMP32 = 0x6
BPF_JNE = 0x50
BPF_JSET = 0x40
BPF_JSGE = 0x70
BPF_JSGT = 0x60
BPF_JSLE = 0xd0
BPF_JSLT = 0xc0
BPF_K = 0x0
BPF_LD = 0x0
BPF_LDX = 0x1
@@ -223,20 +280,33 @@ const (
BPF_MINOR_VERSION = 0x1
BPF_MISC = 0x7
BPF_MOD = 0x90
BPF_MOV = 0xb0
BPF_MSH = 0xa0
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
BPF_PSEUDO_MAP_FD = 0x1
BPF_RET = 0x6
BPF_RSH = 0x70
BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7
BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2
BPF_SOCK_OPS_RTO_CB_FLAG = 0x1
BPF_SOCK_OPS_STATE_CB_FLAG = 0x4
BPF_ST = 0x2
BPF_STX = 0x3
BPF_SUB = 0x10
BPF_TAG_SIZE = 0x8
BPF_TAX = 0x0
BPF_TO_BE = 0x8
BPF_TO_LE = 0x0
BPF_TXA = 0x80
BPF_W = 0x0
BPF_X = 0x8
BPF_XADD = 0xc0
BPF_XOR = 0xa0
BRKINT = 0x2
BS0 = 0x0
@@ -501,6 +571,7 @@ const (
FAN_ALL_MARK_FLAGS = 0xff
FAN_ALL_OUTGOING_EVENTS = 0x3403b
FAN_ALL_PERM_EVENTS = 0x30000
FAN_ATTRIB = 0x4
FAN_AUDIT = 0x10
FAN_CLASS_CONTENT = 0x4
FAN_CLASS_NOTIF = 0x0
@@ -509,8 +580,12 @@ const (
FAN_CLOSE = 0x18
FAN_CLOSE_NOWRITE = 0x10
FAN_CLOSE_WRITE = 0x8
FAN_CREATE = 0x100
FAN_DELETE = 0x200
FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40
FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1
@@ -524,6 +599,10 @@ const (
FAN_MARK_ONLYDIR = 0x8
FAN_MARK_REMOVE = 0x2
FAN_MODIFY = 0x2
FAN_MOVE = 0xc0
FAN_MOVED_FROM = 0x40
FAN_MOVED_TO = 0x80
FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2
FAN_ONDIR = 0x40000000
@@ -532,6 +611,7 @@ const (
FAN_OPEN_EXEC_PERM = 0x40000
FAN_OPEN_PERM = 0x10000
FAN_Q_OVERFLOW = 0x4000
FAN_REPORT_FID = 0x200
FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
@@ -1056,6 +1136,15 @@ const (
MAP_STACK = 0x20000
MAP_SYNC = 0x80000
MAP_TYPE = 0xf
MCAST_BLOCK_SOURCE = 0x2b
MCAST_EXCLUDE = 0x0
MCAST_INCLUDE = 0x1
MCAST_JOIN_GROUP = 0x2a
MCAST_JOIN_SOURCE_GROUP = 0x2e
MCAST_LEAVE_GROUP = 0x2d
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
@@ -1491,6 +1580,7 @@ const (
PR_SET_TSC = 0x1a
PR_SET_UNALIGN = 0x6
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1
@@ -1962,6 +2052,7 @@ const (
SO_ATTACH_REUSEPORT_CBPF = 0x33
SO_ATTACH_REUSEPORT_EBPF = 0x34
SO_BINDTODEVICE = 0x19
SO_BINDTOIFINDEX = 0x3e
SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x6
SO_BSDCOMPAT = 0xe
@@ -2010,6 +2101,8 @@ const (
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x12
SO_RCVTIMEO = 0x14
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x14
SO_REUSEADDR = 0x2
SO_REUSEPORT = 0xf
SO_RXQ_OVFL = 0x28
@@ -2021,9 +2114,17 @@ const (
SO_SNDBUFFORCE = 0x20
SO_SNDLOWAT = 0x13
SO_SNDTIMEO = 0x15
SO_SNDTIMEO_NEW = 0x43
SO_SNDTIMEO_OLD = 0x15
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPING_NEW = 0x41
SO_TIMESTAMPING_OLD = 0x25
SO_TIMESTAMPNS = 0x23
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TIMESTAMP_OLD = 0x1d
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
@@ -2116,6 +2217,8 @@ 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
@@ -2317,8 +2420,10 @@ const (
UBI_IOCMKVOL = 0x40986f00
UBI_IOCRMVOL = 0x40046f01
UBI_IOCRNVOL = 0x51106f03
UBI_IOCRPEB = 0x40046f04
UBI_IOCRSVOL = 0x400c6f02
UBI_IOCSETVOLPROP = 0x40104f06
UBI_IOCSPEB = 0x40046f05
UBI_IOCVOLCRBLK = 0x40804f07
UBI_IOCVOLRMBLK = 0x4f08
UBI_IOCVOLUP = 0x40084f00
@@ -2466,6 +2571,7 @@ const (
XDP_FLAGS_SKB_MODE = 0x2
XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1
XDP_MMAP_OFFSETS = 0x1
XDP_PACKET_HEADROOM = 0x100
XDP_PGOFF_RX_RING = 0x0
XDP_PGOFF_TX_RING = 0x80000000
XDP_RX_RING = 0x2

View File

@@ -197,10 +197,59 @@ const (
BPF_ABS = 0x20
BPF_ADD = 0x0
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_FROM_BE = 0x8
BPF_FROM_LE = 0x0
BPF_FS_MAGIC = 0xcafe4a11
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
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_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_RECOMPUTE_CSUM = 0x1
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_TUNINFO_IPV6 = 0x1
BPF_F_USER_BUILD_ID = 0x800
BPF_F_USER_STACK = 0x100
BPF_F_WRONLY = 0x10
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_ZERO_SEED = 0x40
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -208,8 +257,16 @@ const (
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
BPF_JLE = 0xb0
BPF_JLT = 0xa0
BPF_JMP = 0x5
BPF_JMP32 = 0x6
BPF_JNE = 0x50
BPF_JSET = 0x40
BPF_JSGE = 0x70
BPF_JSGT = 0x60
BPF_JSLE = 0xd0
BPF_JSLT = 0xc0
BPF_K = 0x0
BPF_LD = 0x0
BPF_LDX = 0x1
@@ -223,20 +280,33 @@ const (
BPF_MINOR_VERSION = 0x1
BPF_MISC = 0x7
BPF_MOD = 0x90
BPF_MOV = 0xb0
BPF_MSH = 0xa0
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
BPF_PSEUDO_MAP_FD = 0x1
BPF_RET = 0x6
BPF_RSH = 0x70
BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7
BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2
BPF_SOCK_OPS_RTO_CB_FLAG = 0x1
BPF_SOCK_OPS_STATE_CB_FLAG = 0x4
BPF_ST = 0x2
BPF_STX = 0x3
BPF_SUB = 0x10
BPF_TAG_SIZE = 0x8
BPF_TAX = 0x0
BPF_TO_BE = 0x8
BPF_TO_LE = 0x0
BPF_TXA = 0x80
BPF_W = 0x0
BPF_X = 0x8
BPF_XADD = 0xc0
BPF_XOR = 0xa0
BRKINT = 0x2
BS0 = 0x0
@@ -501,6 +571,7 @@ const (
FAN_ALL_MARK_FLAGS = 0xff
FAN_ALL_OUTGOING_EVENTS = 0x3403b
FAN_ALL_PERM_EVENTS = 0x30000
FAN_ATTRIB = 0x4
FAN_AUDIT = 0x10
FAN_CLASS_CONTENT = 0x4
FAN_CLASS_NOTIF = 0x0
@@ -509,8 +580,12 @@ const (
FAN_CLOSE = 0x18
FAN_CLOSE_NOWRITE = 0x10
FAN_CLOSE_WRITE = 0x8
FAN_CREATE = 0x100
FAN_DELETE = 0x200
FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40
FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1
@@ -524,6 +599,10 @@ const (
FAN_MARK_ONLYDIR = 0x8
FAN_MARK_REMOVE = 0x2
FAN_MODIFY = 0x2
FAN_MOVE = 0xc0
FAN_MOVED_FROM = 0x40
FAN_MOVED_TO = 0x80
FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2
FAN_ONDIR = 0x40000000
@@ -532,6 +611,7 @@ const (
FAN_OPEN_EXEC_PERM = 0x40000
FAN_OPEN_PERM = 0x10000
FAN_Q_OVERFLOW = 0x4000
FAN_REPORT_FID = 0x200
FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
@@ -1054,6 +1134,15 @@ const (
MAP_STACK = 0x20000
MAP_SYNC = 0x80000
MAP_TYPE = 0xf
MCAST_BLOCK_SOURCE = 0x2b
MCAST_EXCLUDE = 0x0
MCAST_INCLUDE = 0x1
MCAST_JOIN_GROUP = 0x2a
MCAST_JOIN_SOURCE_GROUP = 0x2e
MCAST_LEAVE_GROUP = 0x2d
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
@@ -1489,6 +1578,7 @@ const (
PR_SET_TSC = 0x1a
PR_SET_UNALIGN = 0x6
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1
@@ -1968,6 +2058,7 @@ const (
SO_ATTACH_REUSEPORT_CBPF = 0x33
SO_ATTACH_REUSEPORT_EBPF = 0x34
SO_BINDTODEVICE = 0x19
SO_BINDTOIFINDEX = 0x3e
SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x6
SO_BSDCOMPAT = 0xe
@@ -2016,6 +2107,8 @@ const (
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x12
SO_RCVTIMEO = 0x14
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x14
SO_REUSEADDR = 0x2
SO_REUSEPORT = 0xf
SO_RXQ_OVFL = 0x28
@@ -2027,9 +2120,17 @@ const (
SO_SNDBUFFORCE = 0x20
SO_SNDLOWAT = 0x13
SO_SNDTIMEO = 0x15
SO_SNDTIMEO_NEW = 0x43
SO_SNDTIMEO_OLD = 0x15
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPING_NEW = 0x41
SO_TIMESTAMPING_OLD = 0x25
SO_TIMESTAMPNS = 0x23
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TIMESTAMP_OLD = 0x1d
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
@@ -2122,6 +2223,8 @@ 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
@@ -2323,8 +2426,10 @@ const (
UBI_IOCMKVOL = 0x40986f00
UBI_IOCRMVOL = 0x40046f01
UBI_IOCRNVOL = 0x51106f03
UBI_IOCRPEB = 0x40046f04
UBI_IOCRSVOL = 0x400c6f02
UBI_IOCSETVOLPROP = 0x40104f06
UBI_IOCSPEB = 0x40046f05
UBI_IOCVOLCRBLK = 0x40804f07
UBI_IOCVOLRMBLK = 0x4f08
UBI_IOCVOLUP = 0x40084f00
@@ -2472,6 +2577,7 @@ const (
XDP_FLAGS_SKB_MODE = 0x2
XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1
XDP_MMAP_OFFSETS = 0x1
XDP_PACKET_HEADROOM = 0x100
XDP_PGOFF_RX_RING = 0x0
XDP_PGOFF_TX_RING = 0x80000000
XDP_RX_RING = 0x2

View File

@@ -197,10 +197,59 @@ const (
BPF_ABS = 0x20
BPF_ADD = 0x0
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_FROM_BE = 0x8
BPF_FROM_LE = 0x0
BPF_FS_MAGIC = 0xcafe4a11
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
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_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_RECOMPUTE_CSUM = 0x1
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_TUNINFO_IPV6 = 0x1
BPF_F_USER_BUILD_ID = 0x800
BPF_F_USER_STACK = 0x100
BPF_F_WRONLY = 0x10
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_ZERO_SEED = 0x40
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -208,8 +257,16 @@ const (
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
BPF_JLE = 0xb0
BPF_JLT = 0xa0
BPF_JMP = 0x5
BPF_JMP32 = 0x6
BPF_JNE = 0x50
BPF_JSET = 0x40
BPF_JSGE = 0x70
BPF_JSGT = 0x60
BPF_JSLE = 0xd0
BPF_JSLT = 0xc0
BPF_K = 0x0
BPF_LD = 0x0
BPF_LDX = 0x1
@@ -223,20 +280,33 @@ const (
BPF_MINOR_VERSION = 0x1
BPF_MISC = 0x7
BPF_MOD = 0x90
BPF_MOV = 0xb0
BPF_MSH = 0xa0
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
BPF_PSEUDO_MAP_FD = 0x1
BPF_RET = 0x6
BPF_RSH = 0x70
BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7
BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2
BPF_SOCK_OPS_RTO_CB_FLAG = 0x1
BPF_SOCK_OPS_STATE_CB_FLAG = 0x4
BPF_ST = 0x2
BPF_STX = 0x3
BPF_SUB = 0x10
BPF_TAG_SIZE = 0x8
BPF_TAX = 0x0
BPF_TO_BE = 0x8
BPF_TO_LE = 0x0
BPF_TXA = 0x80
BPF_W = 0x0
BPF_X = 0x8
BPF_XADD = 0xc0
BPF_XOR = 0xa0
BRKINT = 0x2
BS0 = 0x0
@@ -503,6 +573,7 @@ const (
FAN_ALL_MARK_FLAGS = 0xff
FAN_ALL_OUTGOING_EVENTS = 0x3403b
FAN_ALL_PERM_EVENTS = 0x30000
FAN_ATTRIB = 0x4
FAN_AUDIT = 0x10
FAN_CLASS_CONTENT = 0x4
FAN_CLASS_NOTIF = 0x0
@@ -511,8 +582,12 @@ const (
FAN_CLOSE = 0x18
FAN_CLOSE_NOWRITE = 0x10
FAN_CLOSE_WRITE = 0x8
FAN_CREATE = 0x100
FAN_DELETE = 0x200
FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40
FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1
@@ -526,6 +601,10 @@ const (
FAN_MARK_ONLYDIR = 0x8
FAN_MARK_REMOVE = 0x2
FAN_MODIFY = 0x2
FAN_MOVE = 0xc0
FAN_MOVED_FROM = 0x40
FAN_MOVED_TO = 0x80
FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2
FAN_ONDIR = 0x40000000
@@ -534,6 +613,7 @@ const (
FAN_OPEN_EXEC_PERM = 0x40000
FAN_OPEN_PERM = 0x10000
FAN_Q_OVERFLOW = 0x4000
FAN_REPORT_FID = 0x200
FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
@@ -1057,6 +1137,15 @@ const (
MAP_STACK = 0x20000
MAP_SYNC = 0x80000
MAP_TYPE = 0xf
MCAST_BLOCK_SOURCE = 0x2b
MCAST_EXCLUDE = 0x0
MCAST_INCLUDE = 0x1
MCAST_JOIN_GROUP = 0x2a
MCAST_JOIN_SOURCE_GROUP = 0x2e
MCAST_LEAVE_GROUP = 0x2d
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
@@ -1492,6 +1581,7 @@ const (
PR_SET_TSC = 0x1a
PR_SET_UNALIGN = 0x6
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1
@@ -1952,6 +2042,7 @@ const (
SO_ATTACH_REUSEPORT_CBPF = 0x33
SO_ATTACH_REUSEPORT_EBPF = 0x34
SO_BINDTODEVICE = 0x19
SO_BINDTOIFINDEX = 0x3e
SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x6
SO_BSDCOMPAT = 0xe
@@ -2000,6 +2091,8 @@ const (
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x12
SO_RCVTIMEO = 0x14
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x14
SO_REUSEADDR = 0x2
SO_REUSEPORT = 0xf
SO_RXQ_OVFL = 0x28
@@ -2011,9 +2104,17 @@ const (
SO_SNDBUFFORCE = 0x20
SO_SNDLOWAT = 0x13
SO_SNDTIMEO = 0x15
SO_SNDTIMEO_NEW = 0x43
SO_SNDTIMEO_OLD = 0x15
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPING_NEW = 0x41
SO_TIMESTAMPING_OLD = 0x25
SO_TIMESTAMPNS = 0x23
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TIMESTAMP_OLD = 0x1d
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
@@ -2107,6 +2208,8 @@ 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
@@ -2308,8 +2411,10 @@ const (
UBI_IOCMKVOL = 0x40986f00
UBI_IOCRMVOL = 0x40046f01
UBI_IOCRNVOL = 0x51106f03
UBI_IOCRPEB = 0x40046f04
UBI_IOCRSVOL = 0x400c6f02
UBI_IOCSETVOLPROP = 0x40104f06
UBI_IOCSPEB = 0x40046f05
UBI_IOCVOLCRBLK = 0x40804f07
UBI_IOCVOLRMBLK = 0x4f08
UBI_IOCVOLUP = 0x40084f00
@@ -2457,6 +2562,7 @@ const (
XDP_FLAGS_SKB_MODE = 0x2
XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1
XDP_MMAP_OFFSETS = 0x1
XDP_PACKET_HEADROOM = 0x100
XDP_PGOFF_RX_RING = 0x0
XDP_PGOFF_TX_RING = 0x80000000
XDP_RX_RING = 0x2

View File

@@ -197,10 +197,59 @@ const (
BPF_ABS = 0x20
BPF_ADD = 0x0
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_FROM_BE = 0x8
BPF_FROM_LE = 0x0
BPF_FS_MAGIC = 0xcafe4a11
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
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_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_RECOMPUTE_CSUM = 0x1
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_TUNINFO_IPV6 = 0x1
BPF_F_USER_BUILD_ID = 0x800
BPF_F_USER_STACK = 0x100
BPF_F_WRONLY = 0x10
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_ZERO_SEED = 0x40
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -208,8 +257,16 @@ const (
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
BPF_JLE = 0xb0
BPF_JLT = 0xa0
BPF_JMP = 0x5
BPF_JMP32 = 0x6
BPF_JNE = 0x50
BPF_JSET = 0x40
BPF_JSGE = 0x70
BPF_JSGT = 0x60
BPF_JSLE = 0xd0
BPF_JSLT = 0xc0
BPF_K = 0x0
BPF_LD = 0x0
BPF_LDX = 0x1
@@ -223,20 +280,33 @@ const (
BPF_MINOR_VERSION = 0x1
BPF_MISC = 0x7
BPF_MOD = 0x90
BPF_MOV = 0xb0
BPF_MSH = 0xa0
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
BPF_PSEUDO_MAP_FD = 0x1
BPF_RET = 0x6
BPF_RSH = 0x70
BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7
BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2
BPF_SOCK_OPS_RTO_CB_FLAG = 0x1
BPF_SOCK_OPS_STATE_CB_FLAG = 0x4
BPF_ST = 0x2
BPF_STX = 0x3
BPF_SUB = 0x10
BPF_TAG_SIZE = 0x8
BPF_TAX = 0x0
BPF_TO_BE = 0x8
BPF_TO_LE = 0x0
BPF_TXA = 0x80
BPF_W = 0x0
BPF_X = 0x8
BPF_XADD = 0xc0
BPF_XOR = 0xa0
BRKINT = 0x2
BS0 = 0x0
@@ -501,6 +571,7 @@ const (
FAN_ALL_MARK_FLAGS = 0xff
FAN_ALL_OUTGOING_EVENTS = 0x3403b
FAN_ALL_PERM_EVENTS = 0x30000
FAN_ATTRIB = 0x4
FAN_AUDIT = 0x10
FAN_CLASS_CONTENT = 0x4
FAN_CLASS_NOTIF = 0x0
@@ -509,8 +580,12 @@ const (
FAN_CLOSE = 0x18
FAN_CLOSE_NOWRITE = 0x10
FAN_CLOSE_WRITE = 0x8
FAN_CREATE = 0x100
FAN_DELETE = 0x200
FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40
FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1
@@ -524,6 +599,10 @@ const (
FAN_MARK_ONLYDIR = 0x8
FAN_MARK_REMOVE = 0x2
FAN_MODIFY = 0x2
FAN_MOVE = 0xc0
FAN_MOVED_FROM = 0x40
FAN_MOVED_TO = 0x80
FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2
FAN_ONDIR = 0x40000000
@@ -532,6 +611,7 @@ const (
FAN_OPEN_EXEC_PERM = 0x40000
FAN_OPEN_PERM = 0x10000
FAN_Q_OVERFLOW = 0x4000
FAN_REPORT_FID = 0x200
FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
@@ -1054,6 +1134,15 @@ const (
MAP_SHARED_VALIDATE = 0x3
MAP_STACK = 0x40000
MAP_TYPE = 0xf
MCAST_BLOCK_SOURCE = 0x2b
MCAST_EXCLUDE = 0x0
MCAST_INCLUDE = 0x1
MCAST_JOIN_GROUP = 0x2a
MCAST_JOIN_SOURCE_GROUP = 0x2e
MCAST_LEAVE_GROUP = 0x2d
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
@@ -1489,6 +1578,7 @@ const (
PR_SET_TSC = 0x1a
PR_SET_UNALIGN = 0x6
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1
@@ -1961,6 +2051,7 @@ const (
SO_ATTACH_REUSEPORT_CBPF = 0x33
SO_ATTACH_REUSEPORT_EBPF = 0x34
SO_BINDTODEVICE = 0x19
SO_BINDTOIFINDEX = 0x3e
SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x20
SO_BSDCOMPAT = 0xe
@@ -2009,6 +2100,8 @@ const (
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x1004
SO_RCVTIMEO = 0x1006
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x1006
SO_REUSEADDR = 0x4
SO_REUSEPORT = 0x200
SO_RXQ_OVFL = 0x28
@@ -2020,10 +2113,18 @@ const (
SO_SNDBUFFORCE = 0x1f
SO_SNDLOWAT = 0x1003
SO_SNDTIMEO = 0x1005
SO_SNDTIMEO_NEW = 0x43
SO_SNDTIMEO_OLD = 0x1005
SO_STYLE = 0x1008
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPING_NEW = 0x41
SO_TIMESTAMPING_OLD = 0x25
SO_TIMESTAMPNS = 0x23
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TIMESTAMP_OLD = 0x1d
SO_TXTIME = 0x3d
SO_TYPE = 0x1008
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
@@ -2115,6 +2216,8 @@ 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
@@ -2318,8 +2421,10 @@ const (
UBI_IOCMKVOL = 0x80986f00
UBI_IOCRMVOL = 0x80046f01
UBI_IOCRNVOL = 0x91106f03
UBI_IOCRPEB = 0x80046f04
UBI_IOCRSVOL = 0x800c6f02
UBI_IOCSETVOLPROP = 0x80104f06
UBI_IOCSPEB = 0x80046f05
UBI_IOCVOLCRBLK = 0x80804f07
UBI_IOCVOLRMBLK = 0x20004f08
UBI_IOCVOLUP = 0x80084f00
@@ -2468,6 +2573,7 @@ const (
XDP_FLAGS_SKB_MODE = 0x2
XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1
XDP_MMAP_OFFSETS = 0x1
XDP_PACKET_HEADROOM = 0x100
XDP_PGOFF_RX_RING = 0x0
XDP_PGOFF_TX_RING = 0x80000000
XDP_RX_RING = 0x2

View File

@@ -197,10 +197,59 @@ const (
BPF_ABS = 0x20
BPF_ADD = 0x0
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_FROM_BE = 0x8
BPF_FROM_LE = 0x0
BPF_FS_MAGIC = 0xcafe4a11
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
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_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_RECOMPUTE_CSUM = 0x1
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_TUNINFO_IPV6 = 0x1
BPF_F_USER_BUILD_ID = 0x800
BPF_F_USER_STACK = 0x100
BPF_F_WRONLY = 0x10
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_ZERO_SEED = 0x40
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -208,8 +257,16 @@ const (
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
BPF_JLE = 0xb0
BPF_JLT = 0xa0
BPF_JMP = 0x5
BPF_JMP32 = 0x6
BPF_JNE = 0x50
BPF_JSET = 0x40
BPF_JSGE = 0x70
BPF_JSGT = 0x60
BPF_JSLE = 0xd0
BPF_JSLT = 0xc0
BPF_K = 0x0
BPF_LD = 0x0
BPF_LDX = 0x1
@@ -223,20 +280,33 @@ const (
BPF_MINOR_VERSION = 0x1
BPF_MISC = 0x7
BPF_MOD = 0x90
BPF_MOV = 0xb0
BPF_MSH = 0xa0
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
BPF_PSEUDO_MAP_FD = 0x1
BPF_RET = 0x6
BPF_RSH = 0x70
BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7
BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2
BPF_SOCK_OPS_RTO_CB_FLAG = 0x1
BPF_SOCK_OPS_STATE_CB_FLAG = 0x4
BPF_ST = 0x2
BPF_STX = 0x3
BPF_SUB = 0x10
BPF_TAG_SIZE = 0x8
BPF_TAX = 0x0
BPF_TO_BE = 0x8
BPF_TO_LE = 0x0
BPF_TXA = 0x80
BPF_W = 0x0
BPF_X = 0x8
BPF_XADD = 0xc0
BPF_XOR = 0xa0
BRKINT = 0x2
BS0 = 0x0
@@ -501,6 +571,7 @@ const (
FAN_ALL_MARK_FLAGS = 0xff
FAN_ALL_OUTGOING_EVENTS = 0x3403b
FAN_ALL_PERM_EVENTS = 0x30000
FAN_ATTRIB = 0x4
FAN_AUDIT = 0x10
FAN_CLASS_CONTENT = 0x4
FAN_CLASS_NOTIF = 0x0
@@ -509,8 +580,12 @@ const (
FAN_CLOSE = 0x18
FAN_CLOSE_NOWRITE = 0x10
FAN_CLOSE_WRITE = 0x8
FAN_CREATE = 0x100
FAN_DELETE = 0x200
FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40
FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1
@@ -524,6 +599,10 @@ const (
FAN_MARK_ONLYDIR = 0x8
FAN_MARK_REMOVE = 0x2
FAN_MODIFY = 0x2
FAN_MOVE = 0xc0
FAN_MOVED_FROM = 0x40
FAN_MOVED_TO = 0x80
FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2
FAN_ONDIR = 0x40000000
@@ -532,6 +611,7 @@ const (
FAN_OPEN_EXEC_PERM = 0x40000
FAN_OPEN_PERM = 0x10000
FAN_Q_OVERFLOW = 0x4000
FAN_REPORT_FID = 0x200
FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
@@ -1054,6 +1134,15 @@ const (
MAP_SHARED_VALIDATE = 0x3
MAP_STACK = 0x40000
MAP_TYPE = 0xf
MCAST_BLOCK_SOURCE = 0x2b
MCAST_EXCLUDE = 0x0
MCAST_INCLUDE = 0x1
MCAST_JOIN_GROUP = 0x2a
MCAST_JOIN_SOURCE_GROUP = 0x2e
MCAST_LEAVE_GROUP = 0x2d
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
@@ -1489,6 +1578,7 @@ const (
PR_SET_TSC = 0x1a
PR_SET_UNALIGN = 0x6
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1
@@ -1961,6 +2051,7 @@ const (
SO_ATTACH_REUSEPORT_CBPF = 0x33
SO_ATTACH_REUSEPORT_EBPF = 0x34
SO_BINDTODEVICE = 0x19
SO_BINDTOIFINDEX = 0x3e
SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x20
SO_BSDCOMPAT = 0xe
@@ -2009,6 +2100,8 @@ const (
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x1004
SO_RCVTIMEO = 0x1006
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x1006
SO_REUSEADDR = 0x4
SO_REUSEPORT = 0x200
SO_RXQ_OVFL = 0x28
@@ -2020,10 +2113,18 @@ const (
SO_SNDBUFFORCE = 0x1f
SO_SNDLOWAT = 0x1003
SO_SNDTIMEO = 0x1005
SO_SNDTIMEO_NEW = 0x43
SO_SNDTIMEO_OLD = 0x1005
SO_STYLE = 0x1008
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPING_NEW = 0x41
SO_TIMESTAMPING_OLD = 0x25
SO_TIMESTAMPNS = 0x23
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TIMESTAMP_OLD = 0x1d
SO_TXTIME = 0x3d
SO_TYPE = 0x1008
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
@@ -2115,6 +2216,8 @@ 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
@@ -2318,8 +2421,10 @@ const (
UBI_IOCMKVOL = 0x80986f00
UBI_IOCRMVOL = 0x80046f01
UBI_IOCRNVOL = 0x91106f03
UBI_IOCRPEB = 0x80046f04
UBI_IOCRSVOL = 0x800c6f02
UBI_IOCSETVOLPROP = 0x80104f06
UBI_IOCSPEB = 0x80046f05
UBI_IOCVOLCRBLK = 0x80804f07
UBI_IOCVOLRMBLK = 0x20004f08
UBI_IOCVOLUP = 0x80084f00
@@ -2468,6 +2573,7 @@ const (
XDP_FLAGS_SKB_MODE = 0x2
XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1
XDP_MMAP_OFFSETS = 0x1
XDP_PACKET_HEADROOM = 0x100
XDP_PGOFF_RX_RING = 0x0
XDP_PGOFF_TX_RING = 0x80000000
XDP_RX_RING = 0x2

View File

@@ -197,10 +197,59 @@ const (
BPF_ABS = 0x20
BPF_ADD = 0x0
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_FROM_BE = 0x8
BPF_FROM_LE = 0x0
BPF_FS_MAGIC = 0xcafe4a11
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
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_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_RECOMPUTE_CSUM = 0x1
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_TUNINFO_IPV6 = 0x1
BPF_F_USER_BUILD_ID = 0x800
BPF_F_USER_STACK = 0x100
BPF_F_WRONLY = 0x10
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_ZERO_SEED = 0x40
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -208,8 +257,16 @@ const (
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
BPF_JLE = 0xb0
BPF_JLT = 0xa0
BPF_JMP = 0x5
BPF_JMP32 = 0x6
BPF_JNE = 0x50
BPF_JSET = 0x40
BPF_JSGE = 0x70
BPF_JSGT = 0x60
BPF_JSLE = 0xd0
BPF_JSLT = 0xc0
BPF_K = 0x0
BPF_LD = 0x0
BPF_LDX = 0x1
@@ -223,20 +280,33 @@ const (
BPF_MINOR_VERSION = 0x1
BPF_MISC = 0x7
BPF_MOD = 0x90
BPF_MOV = 0xb0
BPF_MSH = 0xa0
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
BPF_PSEUDO_MAP_FD = 0x1
BPF_RET = 0x6
BPF_RSH = 0x70
BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7
BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2
BPF_SOCK_OPS_RTO_CB_FLAG = 0x1
BPF_SOCK_OPS_STATE_CB_FLAG = 0x4
BPF_ST = 0x2
BPF_STX = 0x3
BPF_SUB = 0x10
BPF_TAG_SIZE = 0x8
BPF_TAX = 0x0
BPF_TO_BE = 0x8
BPF_TO_LE = 0x0
BPF_TXA = 0x80
BPF_W = 0x0
BPF_X = 0x8
BPF_XADD = 0xc0
BPF_XOR = 0xa0
BRKINT = 0x2
BS0 = 0x0
@@ -501,6 +571,7 @@ const (
FAN_ALL_MARK_FLAGS = 0xff
FAN_ALL_OUTGOING_EVENTS = 0x3403b
FAN_ALL_PERM_EVENTS = 0x30000
FAN_ATTRIB = 0x4
FAN_AUDIT = 0x10
FAN_CLASS_CONTENT = 0x4
FAN_CLASS_NOTIF = 0x0
@@ -509,8 +580,12 @@ const (
FAN_CLOSE = 0x18
FAN_CLOSE_NOWRITE = 0x10
FAN_CLOSE_WRITE = 0x8
FAN_CREATE = 0x100
FAN_DELETE = 0x200
FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40
FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1
@@ -524,6 +599,10 @@ const (
FAN_MARK_ONLYDIR = 0x8
FAN_MARK_REMOVE = 0x2
FAN_MODIFY = 0x2
FAN_MOVE = 0xc0
FAN_MOVED_FROM = 0x40
FAN_MOVED_TO = 0x80
FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2
FAN_ONDIR = 0x40000000
@@ -532,6 +611,7 @@ const (
FAN_OPEN_EXEC_PERM = 0x40000
FAN_OPEN_PERM = 0x10000
FAN_Q_OVERFLOW = 0x4000
FAN_REPORT_FID = 0x200
FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
@@ -1054,6 +1134,15 @@ const (
MAP_SHARED_VALIDATE = 0x3
MAP_STACK = 0x40000
MAP_TYPE = 0xf
MCAST_BLOCK_SOURCE = 0x2b
MCAST_EXCLUDE = 0x0
MCAST_INCLUDE = 0x1
MCAST_JOIN_GROUP = 0x2a
MCAST_JOIN_SOURCE_GROUP = 0x2e
MCAST_LEAVE_GROUP = 0x2d
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
@@ -1489,6 +1578,7 @@ const (
PR_SET_TSC = 0x1a
PR_SET_UNALIGN = 0x6
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1
@@ -1961,6 +2051,7 @@ const (
SO_ATTACH_REUSEPORT_CBPF = 0x33
SO_ATTACH_REUSEPORT_EBPF = 0x34
SO_BINDTODEVICE = 0x19
SO_BINDTOIFINDEX = 0x3e
SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x20
SO_BSDCOMPAT = 0xe
@@ -2009,6 +2100,8 @@ const (
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x1004
SO_RCVTIMEO = 0x1006
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x1006
SO_REUSEADDR = 0x4
SO_REUSEPORT = 0x200
SO_RXQ_OVFL = 0x28
@@ -2020,10 +2113,18 @@ const (
SO_SNDBUFFORCE = 0x1f
SO_SNDLOWAT = 0x1003
SO_SNDTIMEO = 0x1005
SO_SNDTIMEO_NEW = 0x43
SO_SNDTIMEO_OLD = 0x1005
SO_STYLE = 0x1008
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPING_NEW = 0x41
SO_TIMESTAMPING_OLD = 0x25
SO_TIMESTAMPNS = 0x23
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TIMESTAMP_OLD = 0x1d
SO_TXTIME = 0x3d
SO_TYPE = 0x1008
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
@@ -2115,6 +2216,8 @@ 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
@@ -2318,8 +2421,10 @@ const (
UBI_IOCMKVOL = 0x80986f00
UBI_IOCRMVOL = 0x80046f01
UBI_IOCRNVOL = 0x91106f03
UBI_IOCRPEB = 0x80046f04
UBI_IOCRSVOL = 0x800c6f02
UBI_IOCSETVOLPROP = 0x80104f06
UBI_IOCSPEB = 0x80046f05
UBI_IOCVOLCRBLK = 0x80804f07
UBI_IOCVOLRMBLK = 0x20004f08
UBI_IOCVOLUP = 0x80084f00
@@ -2468,6 +2573,7 @@ const (
XDP_FLAGS_SKB_MODE = 0x2
XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1
XDP_MMAP_OFFSETS = 0x1
XDP_PACKET_HEADROOM = 0x100
XDP_PGOFF_RX_RING = 0x0
XDP_PGOFF_TX_RING = 0x80000000
XDP_RX_RING = 0x2

View File

@@ -197,10 +197,59 @@ const (
BPF_ABS = 0x20
BPF_ADD = 0x0
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_FROM_BE = 0x8
BPF_FROM_LE = 0x0
BPF_FS_MAGIC = 0xcafe4a11
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
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_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_RECOMPUTE_CSUM = 0x1
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_TUNINFO_IPV6 = 0x1
BPF_F_USER_BUILD_ID = 0x800
BPF_F_USER_STACK = 0x100
BPF_F_WRONLY = 0x10
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_ZERO_SEED = 0x40
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -208,8 +257,16 @@ const (
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
BPF_JLE = 0xb0
BPF_JLT = 0xa0
BPF_JMP = 0x5
BPF_JMP32 = 0x6
BPF_JNE = 0x50
BPF_JSET = 0x40
BPF_JSGE = 0x70
BPF_JSGT = 0x60
BPF_JSLE = 0xd0
BPF_JSLT = 0xc0
BPF_K = 0x0
BPF_LD = 0x0
BPF_LDX = 0x1
@@ -223,20 +280,33 @@ const (
BPF_MINOR_VERSION = 0x1
BPF_MISC = 0x7
BPF_MOD = 0x90
BPF_MOV = 0xb0
BPF_MSH = 0xa0
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
BPF_PSEUDO_MAP_FD = 0x1
BPF_RET = 0x6
BPF_RSH = 0x70
BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7
BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2
BPF_SOCK_OPS_RTO_CB_FLAG = 0x1
BPF_SOCK_OPS_STATE_CB_FLAG = 0x4
BPF_ST = 0x2
BPF_STX = 0x3
BPF_SUB = 0x10
BPF_TAG_SIZE = 0x8
BPF_TAX = 0x0
BPF_TO_BE = 0x8
BPF_TO_LE = 0x0
BPF_TXA = 0x80
BPF_W = 0x0
BPF_X = 0x8
BPF_XADD = 0xc0
BPF_XOR = 0xa0
BRKINT = 0x2
BS0 = 0x0
@@ -501,6 +571,7 @@ const (
FAN_ALL_MARK_FLAGS = 0xff
FAN_ALL_OUTGOING_EVENTS = 0x3403b
FAN_ALL_PERM_EVENTS = 0x30000
FAN_ATTRIB = 0x4
FAN_AUDIT = 0x10
FAN_CLASS_CONTENT = 0x4
FAN_CLASS_NOTIF = 0x0
@@ -509,8 +580,12 @@ const (
FAN_CLOSE = 0x18
FAN_CLOSE_NOWRITE = 0x10
FAN_CLOSE_WRITE = 0x8
FAN_CREATE = 0x100
FAN_DELETE = 0x200
FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40
FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1
@@ -524,6 +599,10 @@ const (
FAN_MARK_ONLYDIR = 0x8
FAN_MARK_REMOVE = 0x2
FAN_MODIFY = 0x2
FAN_MOVE = 0xc0
FAN_MOVED_FROM = 0x40
FAN_MOVED_TO = 0x80
FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2
FAN_ONDIR = 0x40000000
@@ -532,6 +611,7 @@ const (
FAN_OPEN_EXEC_PERM = 0x40000
FAN_OPEN_PERM = 0x10000
FAN_Q_OVERFLOW = 0x4000
FAN_REPORT_FID = 0x200
FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
@@ -1054,6 +1134,15 @@ const (
MAP_SHARED_VALIDATE = 0x3
MAP_STACK = 0x40000
MAP_TYPE = 0xf
MCAST_BLOCK_SOURCE = 0x2b
MCAST_EXCLUDE = 0x0
MCAST_INCLUDE = 0x1
MCAST_JOIN_GROUP = 0x2a
MCAST_JOIN_SOURCE_GROUP = 0x2e
MCAST_LEAVE_GROUP = 0x2d
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
@@ -1489,6 +1578,7 @@ const (
PR_SET_TSC = 0x1a
PR_SET_UNALIGN = 0x6
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1
@@ -1961,6 +2051,7 @@ const (
SO_ATTACH_REUSEPORT_CBPF = 0x33
SO_ATTACH_REUSEPORT_EBPF = 0x34
SO_BINDTODEVICE = 0x19
SO_BINDTOIFINDEX = 0x3e
SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x20
SO_BSDCOMPAT = 0xe
@@ -2009,6 +2100,8 @@ const (
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x1004
SO_RCVTIMEO = 0x1006
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x1006
SO_REUSEADDR = 0x4
SO_REUSEPORT = 0x200
SO_RXQ_OVFL = 0x28
@@ -2020,10 +2113,18 @@ const (
SO_SNDBUFFORCE = 0x1f
SO_SNDLOWAT = 0x1003
SO_SNDTIMEO = 0x1005
SO_SNDTIMEO_NEW = 0x43
SO_SNDTIMEO_OLD = 0x1005
SO_STYLE = 0x1008
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPING_NEW = 0x41
SO_TIMESTAMPING_OLD = 0x25
SO_TIMESTAMPNS = 0x23
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TIMESTAMP_OLD = 0x1d
SO_TXTIME = 0x3d
SO_TYPE = 0x1008
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
@@ -2115,6 +2216,8 @@ 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
@@ -2318,8 +2421,10 @@ const (
UBI_IOCMKVOL = 0x80986f00
UBI_IOCRMVOL = 0x80046f01
UBI_IOCRNVOL = 0x91106f03
UBI_IOCRPEB = 0x80046f04
UBI_IOCRSVOL = 0x800c6f02
UBI_IOCSETVOLPROP = 0x80104f06
UBI_IOCSPEB = 0x80046f05
UBI_IOCVOLCRBLK = 0x80804f07
UBI_IOCVOLRMBLK = 0x20004f08
UBI_IOCVOLUP = 0x80084f00
@@ -2468,6 +2573,7 @@ const (
XDP_FLAGS_SKB_MODE = 0x2
XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1
XDP_MMAP_OFFSETS = 0x1
XDP_PACKET_HEADROOM = 0x100
XDP_PGOFF_RX_RING = 0x0
XDP_PGOFF_TX_RING = 0x80000000
XDP_RX_RING = 0x2

View File

@@ -197,10 +197,59 @@ const (
BPF_ABS = 0x20
BPF_ADD = 0x0
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_FROM_BE = 0x8
BPF_FROM_LE = 0x0
BPF_FS_MAGIC = 0xcafe4a11
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
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_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_RECOMPUTE_CSUM = 0x1
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_TUNINFO_IPV6 = 0x1
BPF_F_USER_BUILD_ID = 0x800
BPF_F_USER_STACK = 0x100
BPF_F_WRONLY = 0x10
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_ZERO_SEED = 0x40
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -208,8 +257,16 @@ const (
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
BPF_JLE = 0xb0
BPF_JLT = 0xa0
BPF_JMP = 0x5
BPF_JMP32 = 0x6
BPF_JNE = 0x50
BPF_JSET = 0x40
BPF_JSGE = 0x70
BPF_JSGT = 0x60
BPF_JSLE = 0xd0
BPF_JSLT = 0xc0
BPF_K = 0x0
BPF_LD = 0x0
BPF_LDX = 0x1
@@ -223,20 +280,33 @@ const (
BPF_MINOR_VERSION = 0x1
BPF_MISC = 0x7
BPF_MOD = 0x90
BPF_MOV = 0xb0
BPF_MSH = 0xa0
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
BPF_PSEUDO_MAP_FD = 0x1
BPF_RET = 0x6
BPF_RSH = 0x70
BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7
BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2
BPF_SOCK_OPS_RTO_CB_FLAG = 0x1
BPF_SOCK_OPS_STATE_CB_FLAG = 0x4
BPF_ST = 0x2
BPF_STX = 0x3
BPF_SUB = 0x10
BPF_TAG_SIZE = 0x8
BPF_TAX = 0x0
BPF_TO_BE = 0x8
BPF_TO_LE = 0x0
BPF_TXA = 0x80
BPF_W = 0x0
BPF_X = 0x8
BPF_XADD = 0xc0
BPF_XOR = 0xa0
BRKINT = 0x2
BS0 = 0x0
@@ -501,6 +571,7 @@ const (
FAN_ALL_MARK_FLAGS = 0xff
FAN_ALL_OUTGOING_EVENTS = 0x3403b
FAN_ALL_PERM_EVENTS = 0x30000
FAN_ATTRIB = 0x4
FAN_AUDIT = 0x10
FAN_CLASS_CONTENT = 0x4
FAN_CLASS_NOTIF = 0x0
@@ -509,8 +580,12 @@ const (
FAN_CLOSE = 0x18
FAN_CLOSE_NOWRITE = 0x10
FAN_CLOSE_WRITE = 0x8
FAN_CREATE = 0x100
FAN_DELETE = 0x200
FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40
FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1
@@ -524,6 +599,10 @@ const (
FAN_MARK_ONLYDIR = 0x8
FAN_MARK_REMOVE = 0x2
FAN_MODIFY = 0x2
FAN_MOVE = 0xc0
FAN_MOVED_FROM = 0x40
FAN_MOVED_TO = 0x80
FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2
FAN_ONDIR = 0x40000000
@@ -532,6 +611,7 @@ const (
FAN_OPEN_EXEC_PERM = 0x40000
FAN_OPEN_PERM = 0x10000
FAN_Q_OVERFLOW = 0x4000
FAN_REPORT_FID = 0x200
FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
@@ -1053,6 +1133,15 @@ const (
MAP_SHARED_VALIDATE = 0x3
MAP_STACK = 0x20000
MAP_TYPE = 0xf
MCAST_BLOCK_SOURCE = 0x2b
MCAST_EXCLUDE = 0x0
MCAST_INCLUDE = 0x1
MCAST_JOIN_GROUP = 0x2a
MCAST_JOIN_SOURCE_GROUP = 0x2e
MCAST_LEAVE_GROUP = 0x2d
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
MCL_CURRENT = 0x2000
MCL_FUTURE = 0x4000
MCL_ONFAULT = 0x8000
@@ -1491,6 +1580,7 @@ const (
PR_SET_TSC = 0x1a
PR_SET_UNALIGN = 0x6
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1
@@ -2019,6 +2109,7 @@ const (
SO_ATTACH_REUSEPORT_CBPF = 0x33
SO_ATTACH_REUSEPORT_EBPF = 0x34
SO_BINDTODEVICE = 0x19
SO_BINDTOIFINDEX = 0x3e
SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x6
SO_BSDCOMPAT = 0xe
@@ -2067,6 +2158,8 @@ const (
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x10
SO_RCVTIMEO = 0x12
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x12
SO_REUSEADDR = 0x2
SO_REUSEPORT = 0xf
SO_RXQ_OVFL = 0x28
@@ -2078,9 +2171,17 @@ const (
SO_SNDBUFFORCE = 0x20
SO_SNDLOWAT = 0x11
SO_SNDTIMEO = 0x13
SO_SNDTIMEO_NEW = 0x43
SO_SNDTIMEO_OLD = 0x13
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPING_NEW = 0x41
SO_TIMESTAMPING_OLD = 0x25
SO_TIMESTAMPNS = 0x23
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TIMESTAMP_OLD = 0x1d
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
@@ -2171,6 +2272,8 @@ 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
@@ -2378,8 +2481,10 @@ const (
UBI_IOCMKVOL = 0x80986f00
UBI_IOCRMVOL = 0x80046f01
UBI_IOCRNVOL = 0x91106f03
UBI_IOCRPEB = 0x80046f04
UBI_IOCRSVOL = 0x800c6f02
UBI_IOCSETVOLPROP = 0x80104f06
UBI_IOCSPEB = 0x80046f05
UBI_IOCVOLCRBLK = 0x80804f07
UBI_IOCVOLRMBLK = 0x20004f08
UBI_IOCVOLUP = 0x80084f00
@@ -2527,6 +2632,7 @@ const (
XDP_FLAGS_SKB_MODE = 0x2
XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1
XDP_MMAP_OFFSETS = 0x1
XDP_PACKET_HEADROOM = 0x100
XDP_PGOFF_RX_RING = 0x0
XDP_PGOFF_TX_RING = 0x80000000
XDP_RX_RING = 0x2

View File

@@ -197,10 +197,59 @@ const (
BPF_ABS = 0x20
BPF_ADD = 0x0
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_FROM_BE = 0x8
BPF_FROM_LE = 0x0
BPF_FS_MAGIC = 0xcafe4a11
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
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_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_RECOMPUTE_CSUM = 0x1
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_TUNINFO_IPV6 = 0x1
BPF_F_USER_BUILD_ID = 0x800
BPF_F_USER_STACK = 0x100
BPF_F_WRONLY = 0x10
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_ZERO_SEED = 0x40
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -208,8 +257,16 @@ const (
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
BPF_JLE = 0xb0
BPF_JLT = 0xa0
BPF_JMP = 0x5
BPF_JMP32 = 0x6
BPF_JNE = 0x50
BPF_JSET = 0x40
BPF_JSGE = 0x70
BPF_JSGT = 0x60
BPF_JSLE = 0xd0
BPF_JSLT = 0xc0
BPF_K = 0x0
BPF_LD = 0x0
BPF_LDX = 0x1
@@ -223,20 +280,33 @@ const (
BPF_MINOR_VERSION = 0x1
BPF_MISC = 0x7
BPF_MOD = 0x90
BPF_MOV = 0xb0
BPF_MSH = 0xa0
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
BPF_PSEUDO_MAP_FD = 0x1
BPF_RET = 0x6
BPF_RSH = 0x70
BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7
BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2
BPF_SOCK_OPS_RTO_CB_FLAG = 0x1
BPF_SOCK_OPS_STATE_CB_FLAG = 0x4
BPF_ST = 0x2
BPF_STX = 0x3
BPF_SUB = 0x10
BPF_TAG_SIZE = 0x8
BPF_TAX = 0x0
BPF_TO_BE = 0x8
BPF_TO_LE = 0x0
BPF_TXA = 0x80
BPF_W = 0x0
BPF_X = 0x8
BPF_XADD = 0xc0
BPF_XOR = 0xa0
BRKINT = 0x2
BS0 = 0x0
@@ -501,6 +571,7 @@ const (
FAN_ALL_MARK_FLAGS = 0xff
FAN_ALL_OUTGOING_EVENTS = 0x3403b
FAN_ALL_PERM_EVENTS = 0x30000
FAN_ATTRIB = 0x4
FAN_AUDIT = 0x10
FAN_CLASS_CONTENT = 0x4
FAN_CLASS_NOTIF = 0x0
@@ -509,8 +580,12 @@ const (
FAN_CLOSE = 0x18
FAN_CLOSE_NOWRITE = 0x10
FAN_CLOSE_WRITE = 0x8
FAN_CREATE = 0x100
FAN_DELETE = 0x200
FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40
FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1
@@ -524,6 +599,10 @@ const (
FAN_MARK_ONLYDIR = 0x8
FAN_MARK_REMOVE = 0x2
FAN_MODIFY = 0x2
FAN_MOVE = 0xc0
FAN_MOVED_FROM = 0x40
FAN_MOVED_TO = 0x80
FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2
FAN_ONDIR = 0x40000000
@@ -532,6 +611,7 @@ const (
FAN_OPEN_EXEC_PERM = 0x40000
FAN_OPEN_PERM = 0x10000
FAN_Q_OVERFLOW = 0x4000
FAN_REPORT_FID = 0x200
FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
@@ -1053,6 +1133,15 @@ const (
MAP_SHARED_VALIDATE = 0x3
MAP_STACK = 0x20000
MAP_TYPE = 0xf
MCAST_BLOCK_SOURCE = 0x2b
MCAST_EXCLUDE = 0x0
MCAST_INCLUDE = 0x1
MCAST_JOIN_GROUP = 0x2a
MCAST_JOIN_SOURCE_GROUP = 0x2e
MCAST_LEAVE_GROUP = 0x2d
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
MCL_CURRENT = 0x2000
MCL_FUTURE = 0x4000
MCL_ONFAULT = 0x8000
@@ -1491,6 +1580,7 @@ const (
PR_SET_TSC = 0x1a
PR_SET_UNALIGN = 0x6
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1
@@ -2019,6 +2109,7 @@ const (
SO_ATTACH_REUSEPORT_CBPF = 0x33
SO_ATTACH_REUSEPORT_EBPF = 0x34
SO_BINDTODEVICE = 0x19
SO_BINDTOIFINDEX = 0x3e
SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x6
SO_BSDCOMPAT = 0xe
@@ -2067,6 +2158,8 @@ const (
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x10
SO_RCVTIMEO = 0x12
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x12
SO_REUSEADDR = 0x2
SO_REUSEPORT = 0xf
SO_RXQ_OVFL = 0x28
@@ -2078,9 +2171,17 @@ const (
SO_SNDBUFFORCE = 0x20
SO_SNDLOWAT = 0x11
SO_SNDTIMEO = 0x13
SO_SNDTIMEO_NEW = 0x43
SO_SNDTIMEO_OLD = 0x13
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPING_NEW = 0x41
SO_TIMESTAMPING_OLD = 0x25
SO_TIMESTAMPNS = 0x23
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TIMESTAMP_OLD = 0x1d
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
@@ -2171,6 +2272,8 @@ 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
@@ -2378,8 +2481,10 @@ const (
UBI_IOCMKVOL = 0x80986f00
UBI_IOCRMVOL = 0x80046f01
UBI_IOCRNVOL = 0x91106f03
UBI_IOCRPEB = 0x80046f04
UBI_IOCRSVOL = 0x800c6f02
UBI_IOCSETVOLPROP = 0x80104f06
UBI_IOCSPEB = 0x80046f05
UBI_IOCVOLCRBLK = 0x80804f07
UBI_IOCVOLRMBLK = 0x20004f08
UBI_IOCVOLUP = 0x80084f00
@@ -2527,6 +2632,7 @@ const (
XDP_FLAGS_SKB_MODE = 0x2
XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1
XDP_MMAP_OFFSETS = 0x1
XDP_PACKET_HEADROOM = 0x100
XDP_PGOFF_RX_RING = 0x0
XDP_PGOFF_TX_RING = 0x80000000
XDP_RX_RING = 0x2

View File

@@ -197,10 +197,59 @@ const (
BPF_ABS = 0x20
BPF_ADD = 0x0
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_FROM_BE = 0x8
BPF_FROM_LE = 0x0
BPF_FS_MAGIC = 0xcafe4a11
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
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_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_RECOMPUTE_CSUM = 0x1
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_TUNINFO_IPV6 = 0x1
BPF_F_USER_BUILD_ID = 0x800
BPF_F_USER_STACK = 0x100
BPF_F_WRONLY = 0x10
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_ZERO_SEED = 0x40
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -208,8 +257,16 @@ const (
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
BPF_JLE = 0xb0
BPF_JLT = 0xa0
BPF_JMP = 0x5
BPF_JMP32 = 0x6
BPF_JNE = 0x50
BPF_JSET = 0x40
BPF_JSGE = 0x70
BPF_JSGT = 0x60
BPF_JSLE = 0xd0
BPF_JSLT = 0xc0
BPF_K = 0x0
BPF_LD = 0x0
BPF_LDX = 0x1
@@ -223,20 +280,33 @@ const (
BPF_MINOR_VERSION = 0x1
BPF_MISC = 0x7
BPF_MOD = 0x90
BPF_MOV = 0xb0
BPF_MSH = 0xa0
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
BPF_PSEUDO_MAP_FD = 0x1
BPF_RET = 0x6
BPF_RSH = 0x70
BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7
BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2
BPF_SOCK_OPS_RTO_CB_FLAG = 0x1
BPF_SOCK_OPS_STATE_CB_FLAG = 0x4
BPF_ST = 0x2
BPF_STX = 0x3
BPF_SUB = 0x10
BPF_TAG_SIZE = 0x8
BPF_TAX = 0x0
BPF_TO_BE = 0x8
BPF_TO_LE = 0x0
BPF_TXA = 0x80
BPF_W = 0x0
BPF_X = 0x8
BPF_XADD = 0xc0
BPF_XOR = 0xa0
BRKINT = 0x2
BS0 = 0x0
@@ -501,6 +571,7 @@ const (
FAN_ALL_MARK_FLAGS = 0xff
FAN_ALL_OUTGOING_EVENTS = 0x3403b
FAN_ALL_PERM_EVENTS = 0x30000
FAN_ATTRIB = 0x4
FAN_AUDIT = 0x10
FAN_CLASS_CONTENT = 0x4
FAN_CLASS_NOTIF = 0x0
@@ -509,8 +580,12 @@ const (
FAN_CLOSE = 0x18
FAN_CLOSE_NOWRITE = 0x10
FAN_CLOSE_WRITE = 0x8
FAN_CREATE = 0x100
FAN_DELETE = 0x200
FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40
FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1
@@ -524,6 +599,10 @@ const (
FAN_MARK_ONLYDIR = 0x8
FAN_MARK_REMOVE = 0x2
FAN_MODIFY = 0x2
FAN_MOVE = 0xc0
FAN_MOVED_FROM = 0x40
FAN_MOVED_TO = 0x80
FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2
FAN_ONDIR = 0x40000000
@@ -532,6 +611,7 @@ const (
FAN_OPEN_EXEC_PERM = 0x40000
FAN_OPEN_PERM = 0x10000
FAN_Q_OVERFLOW = 0x4000
FAN_REPORT_FID = 0x200
FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
@@ -1054,6 +1134,15 @@ const (
MAP_STACK = 0x20000
MAP_SYNC = 0x80000
MAP_TYPE = 0xf
MCAST_BLOCK_SOURCE = 0x2b
MCAST_EXCLUDE = 0x0
MCAST_INCLUDE = 0x1
MCAST_JOIN_GROUP = 0x2a
MCAST_JOIN_SOURCE_GROUP = 0x2e
MCAST_LEAVE_GROUP = 0x2d
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
@@ -1489,6 +1578,7 @@ const (
PR_SET_TSC = 0x1a
PR_SET_UNALIGN = 0x6
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1
@@ -1949,6 +2039,7 @@ const (
SO_ATTACH_REUSEPORT_CBPF = 0x33
SO_ATTACH_REUSEPORT_EBPF = 0x34
SO_BINDTODEVICE = 0x19
SO_BINDTOIFINDEX = 0x3e
SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x6
SO_BSDCOMPAT = 0xe
@@ -1997,6 +2088,8 @@ const (
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x12
SO_RCVTIMEO = 0x14
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x14
SO_REUSEADDR = 0x2
SO_REUSEPORT = 0xf
SO_RXQ_OVFL = 0x28
@@ -2008,9 +2101,17 @@ const (
SO_SNDBUFFORCE = 0x20
SO_SNDLOWAT = 0x13
SO_SNDTIMEO = 0x15
SO_SNDTIMEO_NEW = 0x43
SO_SNDTIMEO_OLD = 0x15
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPING_NEW = 0x41
SO_TIMESTAMPING_OLD = 0x25
SO_TIMESTAMPNS = 0x23
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TIMESTAMP_OLD = 0x1d
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
@@ -2103,6 +2204,8 @@ 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
@@ -2304,8 +2407,10 @@ const (
UBI_IOCMKVOL = 0x40986f00
UBI_IOCRMVOL = 0x40046f01
UBI_IOCRNVOL = 0x51106f03
UBI_IOCRPEB = 0x40046f04
UBI_IOCRSVOL = 0x400c6f02
UBI_IOCSETVOLPROP = 0x40104f06
UBI_IOCSPEB = 0x40046f05
UBI_IOCVOLCRBLK = 0x40804f07
UBI_IOCVOLRMBLK = 0x4f08
UBI_IOCVOLUP = 0x40084f00
@@ -2453,6 +2558,7 @@ const (
XDP_FLAGS_SKB_MODE = 0x2
XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1
XDP_MMAP_OFFSETS = 0x1
XDP_PACKET_HEADROOM = 0x100
XDP_PGOFF_RX_RING = 0x0
XDP_PGOFF_TX_RING = 0x80000000
XDP_RX_RING = 0x2

View File

@@ -197,10 +197,59 @@ const (
BPF_ABS = 0x20
BPF_ADD = 0x0
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_FROM_BE = 0x8
BPF_FROM_LE = 0x0
BPF_FS_MAGIC = 0xcafe4a11
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
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_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_RECOMPUTE_CSUM = 0x1
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_TUNINFO_IPV6 = 0x1
BPF_F_USER_BUILD_ID = 0x800
BPF_F_USER_STACK = 0x100
BPF_F_WRONLY = 0x10
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_ZERO_SEED = 0x40
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -208,8 +257,16 @@ const (
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
BPF_JLE = 0xb0
BPF_JLT = 0xa0
BPF_JMP = 0x5
BPF_JMP32 = 0x6
BPF_JNE = 0x50
BPF_JSET = 0x40
BPF_JSGE = 0x70
BPF_JSGT = 0x60
BPF_JSLE = 0xd0
BPF_JSLT = 0xc0
BPF_K = 0x0
BPF_LD = 0x0
BPF_LDX = 0x1
@@ -223,20 +280,33 @@ const (
BPF_MINOR_VERSION = 0x1
BPF_MISC = 0x7
BPF_MOD = 0x90
BPF_MOV = 0xb0
BPF_MSH = 0xa0
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
BPF_PSEUDO_MAP_FD = 0x1
BPF_RET = 0x6
BPF_RSH = 0x70
BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7
BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2
BPF_SOCK_OPS_RTO_CB_FLAG = 0x1
BPF_SOCK_OPS_STATE_CB_FLAG = 0x4
BPF_ST = 0x2
BPF_STX = 0x3
BPF_SUB = 0x10
BPF_TAG_SIZE = 0x8
BPF_TAX = 0x0
BPF_TO_BE = 0x8
BPF_TO_LE = 0x0
BPF_TXA = 0x80
BPF_W = 0x0
BPF_X = 0x8
BPF_XADD = 0xc0
BPF_XOR = 0xa0
BRKINT = 0x2
BS0 = 0x0
@@ -501,6 +571,7 @@ const (
FAN_ALL_MARK_FLAGS = 0xff
FAN_ALL_OUTGOING_EVENTS = 0x3403b
FAN_ALL_PERM_EVENTS = 0x30000
FAN_ATTRIB = 0x4
FAN_AUDIT = 0x10
FAN_CLASS_CONTENT = 0x4
FAN_CLASS_NOTIF = 0x0
@@ -509,8 +580,12 @@ const (
FAN_CLOSE = 0x18
FAN_CLOSE_NOWRITE = 0x10
FAN_CLOSE_WRITE = 0x8
FAN_CREATE = 0x100
FAN_DELETE = 0x200
FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40
FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1
@@ -524,6 +599,10 @@ const (
FAN_MARK_ONLYDIR = 0x8
FAN_MARK_REMOVE = 0x2
FAN_MODIFY = 0x2
FAN_MOVE = 0xc0
FAN_MOVED_FROM = 0x40
FAN_MOVED_TO = 0x80
FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2
FAN_ONDIR = 0x40000000
@@ -532,6 +611,7 @@ const (
FAN_OPEN_EXEC_PERM = 0x40000
FAN_OPEN_PERM = 0x10000
FAN_Q_OVERFLOW = 0x4000
FAN_REPORT_FID = 0x200
FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
@@ -1054,6 +1134,15 @@ const (
MAP_STACK = 0x20000
MAP_SYNC = 0x80000
MAP_TYPE = 0xf
MCAST_BLOCK_SOURCE = 0x2b
MCAST_EXCLUDE = 0x0
MCAST_INCLUDE = 0x1
MCAST_JOIN_GROUP = 0x2a
MCAST_JOIN_SOURCE_GROUP = 0x2e
MCAST_LEAVE_GROUP = 0x2d
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
MCL_CURRENT = 0x1
MCL_FUTURE = 0x2
MCL_ONFAULT = 0x4
@@ -1489,6 +1578,7 @@ const (
PR_SET_TSC = 0x1a
PR_SET_UNALIGN = 0x6
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1
@@ -2022,6 +2112,7 @@ const (
SO_ATTACH_REUSEPORT_CBPF = 0x33
SO_ATTACH_REUSEPORT_EBPF = 0x34
SO_BINDTODEVICE = 0x19
SO_BINDTOIFINDEX = 0x3e
SO_BPF_EXTENSIONS = 0x30
SO_BROADCAST = 0x6
SO_BSDCOMPAT = 0xe
@@ -2070,6 +2161,8 @@ const (
SO_RCVBUFFORCE = 0x21
SO_RCVLOWAT = 0x12
SO_RCVTIMEO = 0x14
SO_RCVTIMEO_NEW = 0x42
SO_RCVTIMEO_OLD = 0x14
SO_REUSEADDR = 0x2
SO_REUSEPORT = 0xf
SO_RXQ_OVFL = 0x28
@@ -2081,9 +2174,17 @@ const (
SO_SNDBUFFORCE = 0x20
SO_SNDLOWAT = 0x13
SO_SNDTIMEO = 0x15
SO_SNDTIMEO_NEW = 0x43
SO_SNDTIMEO_OLD = 0x15
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x25
SO_TIMESTAMPING_NEW = 0x41
SO_TIMESTAMPING_OLD = 0x25
SO_TIMESTAMPNS = 0x23
SO_TIMESTAMPNS_NEW = 0x40
SO_TIMESTAMPNS_OLD = 0x23
SO_TIMESTAMP_NEW = 0x3f
SO_TIMESTAMP_OLD = 0x1d
SO_TXTIME = 0x3d
SO_TYPE = 0x3
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
@@ -2176,6 +2277,8 @@ 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
@@ -2377,8 +2480,10 @@ const (
UBI_IOCMKVOL = 0x40986f00
UBI_IOCRMVOL = 0x40046f01
UBI_IOCRNVOL = 0x51106f03
UBI_IOCRPEB = 0x40046f04
UBI_IOCRSVOL = 0x400c6f02
UBI_IOCSETVOLPROP = 0x40104f06
UBI_IOCSPEB = 0x40046f05
UBI_IOCVOLCRBLK = 0x40804f07
UBI_IOCVOLRMBLK = 0x4f08
UBI_IOCVOLUP = 0x40084f00
@@ -2526,6 +2631,7 @@ const (
XDP_FLAGS_SKB_MODE = 0x2
XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1
XDP_MMAP_OFFSETS = 0x1
XDP_PACKET_HEADROOM = 0x100
XDP_PGOFF_RX_RING = 0x0
XDP_PGOFF_TX_RING = 0x80000000
XDP_RX_RING = 0x2

View File

@@ -200,10 +200,59 @@ const (
BPF_ABS = 0x20
BPF_ADD = 0x0
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_FROM_BE = 0x8
BPF_FROM_LE = 0x0
BPF_FS_MAGIC = 0xcafe4a11
BPF_F_ALLOW_MULTI = 0x2
BPF_F_ALLOW_OVERRIDE = 0x1
BPF_F_ANY_ALIGNMENT = 0x2
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_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_RECOMPUTE_CSUM = 0x1
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_TUNINFO_IPV6 = 0x1
BPF_F_USER_BUILD_ID = 0x800
BPF_F_USER_STACK = 0x100
BPF_F_WRONLY = 0x10
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_ZERO_SEED = 0x40
BPF_H = 0x8
BPF_IMM = 0x0
BPF_IND = 0x40
@@ -211,8 +260,16 @@ const (
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
BPF_JLE = 0xb0
BPF_JLT = 0xa0
BPF_JMP = 0x5
BPF_JMP32 = 0x6
BPF_JNE = 0x50
BPF_JSET = 0x40
BPF_JSGE = 0x70
BPF_JSGT = 0x60
BPF_JSLE = 0xd0
BPF_JSLT = 0xc0
BPF_K = 0x0
BPF_LD = 0x0
BPF_LDX = 0x1
@@ -226,20 +283,33 @@ const (
BPF_MINOR_VERSION = 0x1
BPF_MISC = 0x7
BPF_MOD = 0x90
BPF_MOV = 0xb0
BPF_MSH = 0xa0
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
BPF_PSEUDO_MAP_FD = 0x1
BPF_RET = 0x6
BPF_RSH = 0x70
BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7
BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2
BPF_SOCK_OPS_RTO_CB_FLAG = 0x1
BPF_SOCK_OPS_STATE_CB_FLAG = 0x4
BPF_ST = 0x2
BPF_STX = 0x3
BPF_SUB = 0x10
BPF_TAG_SIZE = 0x8
BPF_TAX = 0x0
BPF_TO_BE = 0x8
BPF_TO_LE = 0x0
BPF_TXA = 0x80
BPF_W = 0x0
BPF_X = 0x8
BPF_XADD = 0xc0
BPF_XOR = 0xa0
BRKINT = 0x2
BS0 = 0x0
@@ -505,6 +575,7 @@ const (
FAN_ALL_MARK_FLAGS = 0xff
FAN_ALL_OUTGOING_EVENTS = 0x3403b
FAN_ALL_PERM_EVENTS = 0x30000
FAN_ATTRIB = 0x4
FAN_AUDIT = 0x10
FAN_CLASS_CONTENT = 0x4
FAN_CLASS_NOTIF = 0x0
@@ -513,8 +584,12 @@ const (
FAN_CLOSE = 0x18
FAN_CLOSE_NOWRITE = 0x10
FAN_CLOSE_WRITE = 0x8
FAN_CREATE = 0x100
FAN_DELETE = 0x200
FAN_DELETE_SELF = 0x400
FAN_DENY = 0x2
FAN_ENABLE_AUDIT = 0x40
FAN_EVENT_INFO_TYPE_FID = 0x1
FAN_EVENT_METADATA_LEN = 0x18
FAN_EVENT_ON_CHILD = 0x8000000
FAN_MARK_ADD = 0x1
@@ -528,6 +603,10 @@ const (
FAN_MARK_ONLYDIR = 0x8
FAN_MARK_REMOVE = 0x2
FAN_MODIFY = 0x2
FAN_MOVE = 0xc0
FAN_MOVED_FROM = 0x40
FAN_MOVED_TO = 0x80
FAN_MOVE_SELF = 0x800
FAN_NOFD = -0x1
FAN_NONBLOCK = 0x2
FAN_ONDIR = 0x40000000
@@ -536,6 +615,7 @@ const (
FAN_OPEN_EXEC_PERM = 0x40000
FAN_OPEN_PERM = 0x10000
FAN_Q_OVERFLOW = 0x4000
FAN_REPORT_FID = 0x200
FAN_REPORT_TID = 0x100
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
@@ -1058,6 +1138,15 @@ const (
MAP_SHARED_VALIDATE = 0x3
MAP_STACK = 0x20000
MAP_TYPE = 0xf
MCAST_BLOCK_SOURCE = 0x2b
MCAST_EXCLUDE = 0x0
MCAST_INCLUDE = 0x1
MCAST_JOIN_GROUP = 0x2a
MCAST_JOIN_SOURCE_GROUP = 0x2e
MCAST_LEAVE_GROUP = 0x2d
MCAST_LEAVE_SOURCE_GROUP = 0x2f
MCAST_MSFILTER = 0x30
MCAST_UNBLOCK_SOURCE = 0x2c
MCL_CURRENT = 0x2000
MCL_FUTURE = 0x4000
MCL_ONFAULT = 0x8000
@@ -1493,6 +1582,7 @@ const (
PR_SET_TSC = 0x1a
PR_SET_UNALIGN = 0x6
PR_SPEC_DISABLE = 0x4
PR_SPEC_DISABLE_NOEXEC = 0x10
PR_SPEC_ENABLE = 0x2
PR_SPEC_FORCE_DISABLE = 0x8
PR_SPEC_INDIRECT_BRANCH = 0x1
@@ -2014,6 +2104,7 @@ const (
SO_ATTACH_REUSEPORT_CBPF = 0x35
SO_ATTACH_REUSEPORT_EBPF = 0x36
SO_BINDTODEVICE = 0xd
SO_BINDTOIFINDEX = 0x41
SO_BPF_EXTENSIONS = 0x32
SO_BROADCAST = 0x20
SO_BSDCOMPAT = 0x400
@@ -2062,6 +2153,8 @@ const (
SO_RCVBUFFORCE = 0x100b
SO_RCVLOWAT = 0x800
SO_RCVTIMEO = 0x2000
SO_RCVTIMEO_NEW = 0x44
SO_RCVTIMEO_OLD = 0x2000
SO_REUSEADDR = 0x4
SO_REUSEPORT = 0x200
SO_RXQ_OVFL = 0x24
@@ -2073,9 +2166,17 @@ const (
SO_SNDBUFFORCE = 0x100a
SO_SNDLOWAT = 0x1000
SO_SNDTIMEO = 0x4000
SO_SNDTIMEO_NEW = 0x45
SO_SNDTIMEO_OLD = 0x4000
SO_TIMESTAMP = 0x1d
SO_TIMESTAMPING = 0x23
SO_TIMESTAMPING_NEW = 0x43
SO_TIMESTAMPING_OLD = 0x23
SO_TIMESTAMPNS = 0x21
SO_TIMESTAMPNS_NEW = 0x42
SO_TIMESTAMPNS_OLD = 0x21
SO_TIMESTAMP_NEW = 0x46
SO_TIMESTAMP_OLD = 0x1d
SO_TXTIME = 0x3f
SO_TYPE = 0x1008
SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2
@@ -2167,6 +2268,8 @@ 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
@@ -2366,8 +2469,10 @@ const (
UBI_IOCMKVOL = 0x80986f00
UBI_IOCRMVOL = 0x80046f01
UBI_IOCRNVOL = 0x91106f03
UBI_IOCRPEB = 0x80046f04
UBI_IOCRSVOL = 0x800c6f02
UBI_IOCSETVOLPROP = 0x80104f06
UBI_IOCSPEB = 0x80046f05
UBI_IOCVOLCRBLK = 0x80804f07
UBI_IOCVOLRMBLK = 0x20004f08
UBI_IOCVOLUP = 0x80084f00
@@ -2515,6 +2620,7 @@ const (
XDP_FLAGS_SKB_MODE = 0x2
XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1
XDP_MMAP_OFFSETS = 0x1
XDP_PACKET_HEADROOM = 0x100
XDP_PGOFF_RX_RING = 0x0
XDP_PGOFF_TX_RING = 0x80000000
XDP_RX_RING = 0x2

View File

@@ -859,7 +859,7 @@ func Fchown(fd int, uid int, gid int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fstat(fd int, stat *Stat_t) (err error) {
func fstat(fd int, stat *Stat_t) (err error) {
r0, er := C.fstat(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(stat))))
if r0 == -1 && er != nil {
err = er
@@ -869,7 +869,7 @@ func Fstat(fd int, stat *Stat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
_p0 := uintptr(unsafe.Pointer(C.CString(path)))
r0, er := C.fstatat(C.int(dirfd), C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(stat))), C.int(flags))
if r0 == -1 && er != nil {
@@ -953,7 +953,7 @@ func Listen(s int, n int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Lstat(path string, stat *Stat_t) (err error) {
func lstat(path string, stat *Stat_t) (err error) {
_p0 := uintptr(unsafe.Pointer(C.CString(path)))
r0, er := C.lstat(C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(stat))))
if r0 == -1 && er != nil {
@@ -1071,9 +1071,9 @@ func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n i
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Stat(path string, stat *Stat_t) (err error) {
func stat(path string, statptr *Stat_t) (err error) {
_p0 := uintptr(unsafe.Pointer(C.CString(path)))
r0, er := C.stat(C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(stat))))
r0, er := C.stat(C.uintptr_t(_p0), C.uintptr_t(uintptr(unsafe.Pointer(statptr))))
if r0 == -1 && er != nil {
err = er
}

View File

@@ -803,7 +803,7 @@ func Fchown(fd int, uid int, gid int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fstat(fd int, stat *Stat_t) (err error) {
func fstat(fd int, stat *Stat_t) (err error) {
_, e1 := callfstat(fd, uintptr(unsafe.Pointer(stat)))
if e1 != 0 {
err = errnoErr(e1)
@@ -813,7 +813,7 @@ func Fstat(fd int, stat *Stat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -905,7 +905,7 @@ func Listen(s int, n int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Lstat(path string, stat *Stat_t) (err error) {
func lstat(path string, stat *Stat_t) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
@@ -1023,13 +1023,13 @@ func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n i
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Stat(path string, stat *Stat_t) (err error) {
func stat(path string, statptr *Stat_t) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
return
}
_, e1 := callstat(uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)))
_, e1 := callstat(uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(statptr)))
if e1 != 0 {
err = errnoErr(e1)
}

View File

@@ -941,8 +941,8 @@ func callsplice(rfd int, roff uintptr, wfd int, woff uintptr, len int, flags int
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func callstat(_p0 uintptr, stat uintptr) (r1 uintptr, e1 Errno) {
r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_stat)), 2, _p0, stat, 0, 0, 0, 0)
func callstat(_p0 uintptr, statptr uintptr) (r1 uintptr, e1 Errno) {
r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_stat)), 2, _p0, statptr, 0, 0, 0, 0)
return
}

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