Compare commits

...

7 Commits

Author SHA1 Message Date
Nikolay
180a59119b app/vminsert: properly send rows to legacy vmstorages
Previously, in case when connection to the vmstorage was established in
legacy mode. VMinsert could still forward non metric rows to this
connection. It caused parsing errors at legacy vmstorage.

 This commit drops any non-metric rows designated to the legacy
vmstorages. Because it's not possible correctly re-route it, since most
likely other vmstorages also don't support RPC protocol. Instead
vminsert logs warning message with suggestion to perform an upgrade for
vmstorage.

Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11146
2026-07-09 17:04:04 +02:00
JAYICE
414aa7b3ab lib/promscrape: support overriding max_scrape_size on a per-target basis via the __max_scrape_size__
This commit allows changing max scrape size with meta label - `__max_scrape_size__`.

Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11188
2026-07-09 14:26:53 +02:00
ky505
6155e06ad4 app/vmui: made the changes to prevent overlapping of dropdown in the navbar
Previously, the animation is fast due to which the overlap is occurring. If we can add a delay to animation, or smooth the animation, the UI experience would be much better and smooth.

Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11213
2026-07-08 20:38:52 +02:00
Hui Wang
fb26016beb app/vmselect/metricsql: add fill modifiers support (#11207)
This commit adds new modifiers:
* fill(<value>): Fill in missing series on both sides of the operation with the specified value.
* fill_left(<value>): Fill in missing series on the left side only.
* fill_right(<value>): Fill in missing series on the right side only.

The simplest form is to use fill() to provide a default value for missing series on either side:

`rate(successful_requests_total[5m]) + fill(0) rate(failed_requests_total[5m])`

Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10598
2026-07-08 20:31:39 +02:00
f41gh7
66ac4114ed vendor: update metricsql to v0.87.3 2026-07-08 20:24:57 +02:00
Gautam R
945dc5e42c app/vmbackup: retry S3 HTTP 429 and TooManyRequests errors
vmbackup fails immediately when S3 returns a 429. The SDK retries
TooManyRequestsException but not the short form TooManyRequests, and 429
isn't in the retryable status codes either (only 500/502/503/504 are).
Added both so a rate limit doesn't kill the whole backup.
Note: Followed the same pattern as ExpiredToken and IncompleteBody in
the same retryer config.

Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11218
2026-07-08 16:25:13 +02:00
Max Kotliar
2c9af81fbb app/vmauth: follow-up on #11202
Clean up debug file. Follow-up on
https://github.com/VictoriaMetrics/VictoriaMetrics/pull/11202
2026-07-08 16:37:12 +03:00
51 changed files with 708 additions and 338 deletions

View File

@@ -172,7 +172,13 @@ func newBinaryOpFunc(bf func(left, right float64, isBool bool) float64) binaryOp
left = removeEmptySeries(left)
right = removeEmptySeries(right)
}
if len(left) == 0 || len(right) == 0 {
if len(left) == 0 && len(right) == 0 {
return nil, nil
}
if len(left) == 0 && bfa.be.FillLeft == nil {
return nil, nil
}
if len(right) == 0 && bfa.be.FillRight == nil {
return nil, nil
}
left, right, dst, err := adjustBinaryOpTags(bfa.be, left, right)
@@ -183,6 +189,8 @@ func newBinaryOpFunc(bf func(left, right float64, isBool bool) float64) binaryOp
logger.Panicf("BUG: len(left) must match len(right) and len(dst); got %d vs %d vs %d", len(left), len(right), len(dst))
}
isBool := bfa.be.Bool
fillLeft := bfa.be.FillLeft
fillRight := bfa.be.FillRight
for i, tsLeft := range left {
leftValues := tsLeft.Values
rightValues := right[i].Values
@@ -193,6 +201,19 @@ func newBinaryOpFunc(bf func(left, right float64, isBool bool) float64) binaryOp
}
for j, a := range leftValues {
b := rightValues[j]
leftIsNaN := math.IsNaN(a)
rightIsNaN := math.IsNaN(b)
// apply the fill value when either the left or right side is NaN, but not both.
if leftIsNaN && rightIsNaN {
dstValues[j] = bf(a, b, isBool)
continue
}
if leftIsNaN && fillLeft != nil {
a = fillLeft.N
}
if rightIsNaN && fillRight != nil {
b = fillRight.N
}
dstValues[j] = bf(a, b, isBool)
}
}
@@ -226,7 +247,7 @@ func adjustBinaryOpTags(be *metricsql.BinaryOpExpr, left, right []*timeseries) (
}
}
// Slow path: `vector op vector` or `a op {on|ignoring} {group_left|group_right} b`
// Slow path: `vector op vector` or `a op {on|ignoring} {group_left|group_right} {fill|fill_left|fill_right} b`
var rvsLeft, rvsRight []*timeseries
mLeft, mRight := createTimeseriesMapByTagSet(be, left, right)
joinOp := strings.ToLower(be.JoinModifier.Op)
@@ -239,10 +260,27 @@ func adjustBinaryOpTags(be *metricsql.BinaryOpExpr, left, right []*timeseries) (
// Add __name__ to groupTags if metric name must be preserved.
groupTags = append(groupTags[:len(groupTags):len(groupTags)], "__name__")
}
// Add missing keys from mRight to mLeft when fill_left()/fill() modifier is used
if be.FillLeft != nil {
for k := range mRight {
if _, ok := mLeft[k]; !ok {
mLeft[k] = nil
}
}
}
for k, tssLeft := range mLeft {
tssRight := mRight[k]
if len(tssLeft) == 0 {
if be.FillLeft == nil {
logger.Panicf("BUG: unexpected empty tssLeft for key %q when FillLeft is nil", k)
}
tssLeft = []*timeseries{newFillTimeseries(be, tssRight[0])}
}
if len(tssRight) == 0 {
continue
if be.FillRight == nil {
continue
}
tssRight = []*timeseries{newFillTimeseries(be, tssLeft[0])}
}
switch joinOp {
case "group_left":
@@ -287,6 +325,28 @@ func adjustBinaryOpTags(be *metricsql.BinaryOpExpr, left, right []*timeseries) (
return rvsLeft, rvsRight, dst, nil
}
// newFillTimeseries returns a time series filled with NaN values for the fill_left()/fill_right()/fill() modifiers.
// These NaN values will be replaced later with the fill value if needed.
func newFillTimeseries(be *metricsql.BinaryOpExpr, src *timeseries) *timeseries {
var ts timeseries
ts.CopyFromShallowTimestamps(src)
if !be.KeepMetricNames {
ts.MetricName.ResetMetricGroup()
}
groupTags := be.GroupModifier.Args
switch strings.ToLower(be.GroupModifier.Op) {
case "on":
ts.MetricName.RemoveTagsOn(groupTags)
default:
ts.MetricName.RemoveTagsIgnoring(groupTags)
}
values := ts.Values
for i := range values {
values[i] = math.NaN()
}
return &ts
}
func ensureSingleTimeseries(side string, be *metricsql.BinaryOpExpr, tss []*timeseries) error {
if len(tss) == 0 {
logger.Panicf("BUG: tss must contain at least one value")

View File

@@ -424,18 +424,7 @@ func evalBinaryOp(qt *querytracer.Tracer, ec *EvalConfig, be *metricsql.BinaryOp
if bf == nil {
return nil, fmt.Errorf(`unknown binary op %q`, be.Op)
}
var err error
var tssLeft, tssRight []*timeseries
switch strings.ToLower(be.Op) {
case "and", "if":
// Fetch right-side series at first, since it usually contains
// lower number of time series for `and` and `if` operator.
// This should produce more specific label filters for the left side of the query.
// This, in turn, should reduce the time to select series for the left side of the query.
tssRight, tssLeft, err = execBinaryOpArgs(qt, ec, be.Right, be.Left, be)
default:
tssLeft, tssRight, err = execBinaryOpArgs(qt, ec, be.Left, be.Right, be)
}
tssLeft, tssRight, err := execBinaryOpArgs(qt, ec, be)
if err != nil {
return nil, fmt.Errorf("cannot execute %q: %w", be.AppendString(nil), err)
}
@@ -451,6 +440,29 @@ func evalBinaryOp(qt *querytracer.Tracer, ec *EvalConfig, be *metricsql.BinaryOp
return rv, nil
}
// binaryOpEvalOrder might change the order of evaluation of the left and right sides of a binary operation,
// when there is chance to push down common label filters from exprFirst to exprSecond in the following executions.
func binaryOpEvalOrder(be *metricsql.BinaryOpExpr) (exprFirst, exprSecond metricsql.Expr) {
exprFirst, exprSecond = be.Left, be.Right
switch strings.ToLower(be.Op) {
case "and", "if":
// For `and` and `if`, fetch the right-side series first, since it usually contains
// fewer time series and yields more specific filters for the left side.
exprFirst, exprSecond = be.Right, be.Left
}
if be.FillLeft != nil && be.FillRight == nil {
// For `fill_left(<value>)`, the unmatched series can only come from the right side, so evaluate it first.
exprFirst, exprSecond = be.Right, be.Left
}
return exprFirst, exprSecond
}
// canPushdownCommonFilters decides if common label filters can be pushed down from one side of a binary operation to the other.
//
// Common filters cannot be pushed down when:
// - the operator is `or` or `default`;
// - either side is an aggregation function without explicit grouping;
// - fill(<value>) modifier is used.
func canPushdownCommonFilters(be *metricsql.BinaryOpExpr) bool {
switch strings.ToLower(be.Op) {
case "or", "default":
@@ -459,6 +471,10 @@ func canPushdownCommonFilters(be *metricsql.BinaryOpExpr) bool {
if isAggrFuncWithoutGrouping(be.Left) || isAggrFuncWithoutGrouping(be.Right) {
return false
}
// Filters cannot be propagated when fill(<value>) modifier is used.
if be.FillLeft != nil && be.FillRight != nil {
return false
}
return true
}
@@ -470,7 +486,15 @@ func isAggrFuncWithoutGrouping(e metricsql.Expr) bool {
return len(afe.Modifier.Args) == 0
}
func execBinaryOpArgs(qt *querytracer.Tracer, ec *EvalConfig, exprFirst, exprSecond metricsql.Expr, be *metricsql.BinaryOpExpr) ([]*timeseries, []*timeseries, error) {
func execBinaryOpArgs(qt *querytracer.Tracer, ec *EvalConfig, be *metricsql.BinaryOpExpr) ([]*timeseries, []*timeseries, error) {
exprFirst, exprSecond := binaryOpEvalOrder(be)
firstIsLeft := exprFirst == be.Left
sortResult := func(tssFirst, tssSecond []*timeseries) ([]*timeseries, []*timeseries, error) {
if firstIsLeft {
return tssFirst, tssSecond, nil
}
return tssSecond, tssFirst, nil
}
if canPushdownCommonFilters(be) {
// Execute binary operation in the following way:
//
@@ -512,7 +536,7 @@ func execBinaryOpArgs(qt *querytracer.Tracer, ec *EvalConfig, exprFirst, exprSec
if err != nil {
return nil, nil, err
}
return tssFirst, tssSecond, nil
return sortResult(tssFirst, tssSecond)
}
// Execute exprFirst and exprSecond sequentially if there are cacheable repeated subexpressions
@@ -568,7 +592,7 @@ func execBinaryOpArgs(qt *querytracer.Tracer, ec *EvalConfig, exprFirst, exprSec
if errSecond != nil {
return nil, nil, errSecond
}
return tssFirst, tssSecond, nil
return sortResult(tssFirst, tssSecond)
}
func shouldOptimizeRepeatedBinaryOpSubexprs(ec *EvalConfig, exprFirst, exprSecond metricsql.Expr) bool {

View File

@@ -4006,6 +4006,275 @@ func TestExecSuccess(t *testing.T) {
resultExpected := []netstorage.Result{r1, r2}
f(q, resultExpected)
})
t.Run(`vector + vector fill()`, func(t *testing.T) {
t.Parallel()
q := `sort_by_label((
label_set(1, "foo", "common")
or label_set(2, "foo", "left_only")
) + fill(0) (
label_set(3, "foo", "common")
or label_set(4, "foo", "right_only")
), "foo")`
r1 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{4, 4, 4, 4, 4, 4},
Timestamps: timestampsExpected,
}
r1.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("common"),
}}
r2 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{2, 2, 2, 2, 2, 2},
Timestamps: timestampsExpected,
}
r2.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("left_only"),
}}
r3 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{4, 4, 4, 4, 4, 4},
Timestamps: timestampsExpected,
}
r3.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("right_only"),
}}
resultExpected := []netstorage.Result{r1, r2, r3}
f(q, resultExpected)
})
t.Run(`vector + vector fill() both sides NaN case`, func(t *testing.T) {
t.Parallel()
q := `(
label_set(time() <= 1200, "foo", "common")
) + fill(10) (
label_set(time() >= 1600, "foo", "common")
)`
r := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{1010, 1210, nan, 1610, 1810, 2010},
Timestamps: timestampsExpected,
}
r.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("common"),
}}
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`vector + vector fill_left() fill_right()`, func(t *testing.T) {
t.Parallel()
q := `sort_by_label((
label_set(1, "foo", "common")
or label_set(2, "foo", "left_only")
) + fill_left(10) fill_right(20) (
label_set(3, "foo", "common")
or label_set(4, "foo", "right_only")
), "foo")`
r1 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{4, 4, 4, 4, 4, 4},
Timestamps: timestampsExpected,
}
r1.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("common"),
}}
r2 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{22, 22, 22, 22, 22, 22},
Timestamps: timestampsExpected,
}
r2.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("left_only"),
}}
r3 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{14, 14, 14, 14, 14, 14},
Timestamps: timestampsExpected,
}
r3.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("right_only"),
}}
resultExpected := []netstorage.Result{r1, r2, r3}
f(q, resultExpected)
})
t.Run(`vector + vector fill_right() only`, func(t *testing.T) {
t.Parallel()
q := `sort_by_label((
label_set(1, "foo", "common")
or label_set(2, "foo", "left_only")
) + fill_right(20) (
label_set(3, "foo", "common")
or label_set(4, "foo", "right_only")
), "foo")`
r1 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{4, 4, 4, 4, 4, 4},
Timestamps: timestampsExpected,
}
r1.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("common"),
}}
r2 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{22, 22, 22, 22, 22, 22},
Timestamps: timestampsExpected,
}
r2.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("left_only"),
}}
resultExpected := []netstorage.Result{r1, r2}
f(q, resultExpected)
})
t.Run(`vector + vector on() fill()`, func(t *testing.T) {
t.Parallel()
q := `sort_by_label((
label_set(1, "foo", "common", "extra", "l")
or label_set(2, "foo", "left_only", "extra", "l")
) + on(foo) fill(0) (
label_set(3, "foo", "common", "extra", "r")
or label_set(4, "foo", "right_only", "extra", "r")
), "foo")`
r1 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{4, 4, 4, 4, 4, 4},
Timestamps: timestampsExpected,
}
r1.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("common"),
}}
r2 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{2, 2, 2, 2, 2, 2},
Timestamps: timestampsExpected,
}
r2.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("left_only"),
}}
r3 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{4, 4, 4, 4, 4, 4},
Timestamps: timestampsExpected,
}
r3.MetricName.Tags = []storage.Tag{{
Key: []byte("foo"),
Value: []byte("right_only"),
}}
resultExpected := []netstorage.Result{r1, r2, r3}
f(q, resultExpected)
})
t.Run(`vector + vector on() group_left() fill_right()`, func(t *testing.T) {
t.Parallel()
q := `sort_by_label((
label_set(1, "method", "get", "code", "500")
or label_set(2, "method", "get", "code", "404")
or label_set(3, "method", "put", "code", "501")
) + on(method) group_left() fill_right(0) (
label_set(10, "method", "get")
), "method", "code")`
r1 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{12, 12, 12, 12, 12, 12},
Timestamps: timestampsExpected,
}
r1.MetricName.Tags = []storage.Tag{
{
Key: []byte("code"),
Value: []byte("404"),
},
{
Key: []byte("method"),
Value: []byte("get"),
},
}
r2 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{11, 11, 11, 11, 11, 11},
Timestamps: timestampsExpected,
}
r2.MetricName.Tags = []storage.Tag{
{
Key: []byte("code"),
Value: []byte("500"),
},
{
Key: []byte("method"),
Value: []byte("get"),
},
}
r3 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{3, 3, 3, 3, 3, 3},
Timestamps: timestampsExpected,
}
r3.MetricName.Tags = []storage.Tag{
{
Key: []byte("code"),
Value: []byte("501"),
},
{
Key: []byte("method"),
Value: []byte("put"),
},
}
resultExpected := []netstorage.Result{r1, r2, r3}
f(q, resultExpected)
})
t.Run(`vector / vector ignoring() fill()`, func(t *testing.T) {
t.Parallel()
q := `sort_by_label((
label_set(6, "method", "get", "code", "500")
or label_set(1, "method", "put", "code", "500")
) / ignoring(code) fill(0) (
label_set(12, "method", "get")
or label_set(5, "method", "post")
or label_set(10, "method", "put")
), "method")`
r1 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
Timestamps: timestampsExpected,
}
r1.MetricName.Tags = []storage.Tag{
{
Key: []byte("method"),
Value: []byte("get"),
},
}
r2 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{0, 0, 0, 0, 0, 0},
Timestamps: timestampsExpected,
}
r2.MetricName.Tags = []storage.Tag{
{
Key: []byte("method"),
Value: []byte("post"),
},
}
r3 := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{0.1, 0.1, 0.1, 0.1, 0.1, 0.1},
Timestamps: timestampsExpected,
}
r3.MetricName.Tags = []storage.Tag{
{
Key: []byte("method"),
Value: []byte("put"),
},
}
resultExpected := []netstorage.Result{r1, r2, r3}
f(q, resultExpected)
})
t.Run(`histogram_quantile(scalar)`, func(t *testing.T) {
t.Parallel()
q := `histogram_quantile(0.6, time())`

View File

@@ -17,10 +17,12 @@ interface HeaderNavProps {
const HeaderNav: FC<HeaderNavProps> = ({ color, background, direction }) => {
const { pathname } = useLocation();
const [activeMenu, setActiveMenu] = useState(pathname);
const [openMenu, setOpenMenu] = useState<string | null>(null);
const menu = useNavigationMenu();
useEffect(() => {
setActiveMenu(pathname);
setOpenMenu(null);
}, [pathname]);
return (
@@ -41,6 +43,8 @@ const HeaderNav: FC<HeaderNavProps> = ({ color, background, direction }) => {
color={color}
background={background}
direction={direction}
openMenu={openMenu}
setOpenMenu={setOpenMenu}
/>
)
: (

View File

@@ -1,11 +1,8 @@
import { FC, useRef, useState } from "preact/compat";
import { useLocation } from "react-router-dom";
import { FC, useRef, useState, Dispatch, SetStateAction } from "preact/compat";
import classNames from "classnames";
import { ArrowDropDownIcon } from "../../../components/Main/Icons";
import Popper from "../../../components/Main/Popper/Popper";
import NavItem from "./NavItem";
import { useEffect } from "react";
import useBoolean from "../../../hooks/useBoolean";
import { NavigationItem, NavigationItemType } from "../../../router/navigation";
interface NavItemProps {
@@ -15,6 +12,8 @@ interface NavItemProps {
color?: string
background?: string
direction?: "row" | "column"
openMenu: string | null,
setOpenMenu: Dispatch<SetStateAction<string | null>>,
}
const NavSubItem: FC<NavItemProps> = ({
@@ -23,21 +22,18 @@ const NavSubItem: FC<NavItemProps> = ({
color,
background,
submenu,
direction = "row"
direction = "row",
openMenu,
setOpenMenu,
}) => {
const { pathname } = useLocation();
const [menuTimeout, setMenuTimeout] = useState<NodeJS.Timeout | null>(null);
const buttonRef = useRef<HTMLDivElement>(null);
const {
value: openSubmenu,
setFalse: handleCloseSubmenu,
setTrue: setOpenSubmenu,
} = useBoolean(false);
const openSubmenu = openMenu === label;
const handleCloseSubmenu = () => setOpenMenu(prev => (prev === label ? null : prev));
const handleOpenSubmenu = () => {
if (direction === "row" || !openSubmenu) setOpenSubmenu();
if (direction === "row" || !openSubmenu) setOpenMenu(label);
if (direction === "column" && openSubmenu) handleCloseSubmenu();
if (direction === "row" && menuTimeout) clearTimeout(menuTimeout);
};
@@ -52,10 +48,6 @@ const NavSubItem: FC<NavItemProps> = ({
if (menuTimeout) clearTimeout(menuTimeout);
};
useEffect(() => {
handleCloseSubmenu();
}, [pathname]);
return (
<div
className={classNames({

View File

View File

@@ -26,7 +26,13 @@ See also [LTS releases](https://docs.victoriametrics.com/victoriametrics/lts-rel
## tip
* FEATURE: [MetricsQL](https://docs.victoriametrics.com/victoriametrics/metricsql/): support `fill` modifiers to allow missing series on either side of a binary operation to be filled with a provided default value. See [#10598](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10598).
* FEATURE: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/) and [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/): allow overriding `max_scrape_size` on a per-target basis via the `__max_scrape_size__` label during target relabeling. See [#11188](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11188).
* BUGFIX: `vminsert` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): Now drops metadata blocks when communicating with vmstorage nodes over the legacy RPC protocol. To avoid this limitation, upgrade `vmstorage` to a version that supports the new RPC protocol (>= [v1.137.0](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/docs/victoriametrics/changelog/CHANGELOG.md#v11370)). See [#11146](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11146).
* BUGFIX: [vmbackup](https://docs.victoriametrics.com/victoriametrics/vmbackup/) and [vmbackupmanager](https://docs.victoriametrics.com/victoriametrics/vmbackupmanager/): retry S3 requests failing with `HTTP 429` status code or `TooManyRequests` error code. Previously such requests were not retried, so a short burst of rate limiting would fail the whole backup. See [#11218](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11218). Thanks to @gautamrizwani for contribution.
* BUGFIX: `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): properly apply limit to metrics metadata response. See [#11139](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/11139).
* BUGFIX: [vmui](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#vmui): keep only one header navigation dropdown (`Explore`, `Tools`) open at a time. Previously, hovering across two dropdowns could briefly leave both open due to the close delay. See [#11224](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/11224). Thanks to @antedotee for contribution.
## [v1.147.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.147.0)

View File

@@ -1923,6 +1923,9 @@ scrape_configs:
# Example values:
# - "10MiB" - 10 * 1024 * 1024 bytes
# - "100MB" - 100 * 1000 * 1000 bytes
# The max_scrape_size can be set on a per-target basis by specifying `__max_scrape_size__`
# label during target relabeling phase.
# See https://docs.victoriametrics.com/victoriametrics/relabeling/
#
# max_scrape_size: <size>

4
go.mod
View File

@@ -11,7 +11,7 @@ require (
github.com/VictoriaMetrics/easyproto v1.2.0
github.com/VictoriaMetrics/fastcache v1.13.3
github.com/VictoriaMetrics/metrics v1.44.0
github.com/VictoriaMetrics/metricsql v0.87.2
github.com/VictoriaMetrics/metricsql v0.87.3
github.com/aws/aws-sdk-go-v2 v1.42.0
github.com/aws/aws-sdk-go-v2/config v1.32.25
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.22.27
@@ -36,7 +36,7 @@ require (
github.com/valyala/quicktemplate v1.8.0
golang.org/x/net v0.56.0
golang.org/x/oauth2 v0.36.0
golang.org/x/sys v0.46.0
golang.org/x/sys v0.47.0
google.golang.org/api v0.284.0
gopkg.in/yaml.v2 v2.4.0
)

4
go.sum
View File

@@ -62,6 +62,8 @@ github.com/VictoriaMetrics/metrics v1.44.0 h1:Fr8yqQSV+ZfYaDD/anqk1E8e9YPgfleSle
github.com/VictoriaMetrics/metrics v1.44.0/go.mod h1:xDM82ULLYCYdFRgQ2JBxi8Uf1+8En1So9YUwlGTOqTc=
github.com/VictoriaMetrics/metricsql v0.87.2 h1:7OsrcDBWREWKqqpnFyIUEOM4FNv2qHvCoww2GYz3Tc0=
github.com/VictoriaMetrics/metricsql v0.87.2/go.mod h1:d4EisFO6ONP/HIGDYTAtwrejJBBeKGQYiRl095bS4QQ=
github.com/VictoriaMetrics/metricsql v0.87.3 h1:JU4JnVKSC5Vp3b4AvogXyOAjkz1iFF9n1KBMphS4WO8=
github.com/VictoriaMetrics/metricsql v0.87.3/go.mod h1:d4EisFO6ONP/HIGDYTAtwrejJBBeKGQYiRl095bS4QQ=
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0=
@@ -544,6 +546,8 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@@ -164,6 +164,14 @@ func (fs *FS) Init(ctx context.Context) error {
// when using EKS Pod Identity or similar.
// See: https://github.com/VictoriaMetrics/VictoriaMetrics/issues/9280
"ExpiredToken": {},
// S3-compatible stores may return TooManyRequests instead of TooManyRequestsException.
// See: https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11218
"TooManyRequests": {},
},
}, retry.RetryableHTTPStatusCode{
Codes: map[int]struct{}{
// S3-compatible stores may return HTTP 429 for rate limiting instead of HTTP 503.
429: {},
},
}, retry.IsErrorRetryableFunc(func(err error) aws.Ternary {
if errors.Is(err, io.ErrUnexpectedEOF) {

View File

@@ -1271,6 +1271,17 @@ func (swc *scrapeWorkConfig) getScrapeWork(target string, extraLabels, metaLabel
}
scrapeTimeout = d
}
// Read max_scrape_size option from __max_scrape_size__ label.
targetMaxScrapeSize := swc.maxScrapeSize
if s := labels.Get("__max_scrape_size__"); len(s) > 0 {
n, err := flagutil.ParseBytes(s)
if err != nil {
return nil, fmt.Errorf("cannot parse __max_scrape_size__=%q: %w", s, err)
}
if n > 0 {
targetMaxScrapeSize = n
}
}
// Read series_limit option from __series_limit__ label.
// See https://docs.victoriametrics.com/victoriametrics/vmagent/#cardinality-limiter
seriesLimit := swc.seriesLimit
@@ -1333,7 +1344,7 @@ func (swc *scrapeWorkConfig) getScrapeWork(target string, extraLabels, metaLabel
ScrapeURL: scrapeURL,
ScrapeInterval: scrapeInterval,
ScrapeTimeout: scrapeTimeout,
MaxScrapeSize: swc.maxScrapeSize,
MaxScrapeSize: targetMaxScrapeSize,
HonorLabels: swc.honorLabels,
HonorTimestamps: swc.honorTimestamps,
DenyRedirects: swc.denyRedirects,

View File

@@ -1153,6 +1153,57 @@ scrape_configs:
})
f(`
scrape_configs:
- job_name: foo
max_scrape_size: 8MiB
relabel_configs:
- source_labels: [__address__]
regex: foo1:.*
target_label: __max_scrape_size__
replacement: 2.5MiB
- source_labels: [__address__]
regex: foo2:.*
target_label: __max_scrape_size__
replacement: -1
static_configs:
- targets: ["foo1:1234", "foo2:1234", "foo3:1234"]
`, []*ScrapeWork{
{
ScrapeURL: "http://foo1:1234/metrics",
ScrapeInterval: defaultScrapeInterval,
ScrapeTimeout: defaultScrapeTimeout,
MaxScrapeSize: 2.5 * 1024 * 1024,
Labels: promutil.NewLabelsFromMap(map[string]string{
"instance": "foo1:1234",
"job": "foo",
}),
jobNameOriginal: "foo",
},
// invalid __max_scrape_size__ will be ignored
{
ScrapeURL: "http://foo2:1234/metrics",
ScrapeInterval: defaultScrapeInterval,
ScrapeTimeout: defaultScrapeTimeout,
MaxScrapeSize: 8 * 1024 * 1024,
Labels: promutil.NewLabelsFromMap(map[string]string{
"instance": "foo2:1234",
"job": "foo",
}),
jobNameOriginal: "foo",
},
{
ScrapeURL: "http://foo3:1234/metrics",
ScrapeInterval: defaultScrapeInterval,
ScrapeTimeout: defaultScrapeTimeout,
MaxScrapeSize: 8 * 1024 * 1024,
Labels: promutil.NewLabelsFromMap(map[string]string{
"instance": "foo3:1234",
"job": "foo",
}),
jobNameOriginal: "foo",
},
})
f(`
scrape_configs:
- job_name: foo
static_configs:
- targets: ["foo.bar:1234"]

View File

@@ -73,6 +73,16 @@ func isBinaryOp(op string) bool {
return binaryOps[op]
}
func isSetOperator(op string) bool {
op = strings.ToLower(op)
switch op {
case "and", "or", "unless", "if", "ifnot", "default":
return true
default:
return false
}
}
func binaryOpPriority(op string) int {
op = strings.ToLower(op)
return binaryOpPriorities[op]
@@ -123,6 +133,16 @@ func isBinaryOpBoolModifier(s string) bool {
return s == "bool"
}
func isBinaryOpFillModifier(s string) bool {
s = strings.ToLower(s)
switch s {
case "fill", "fill_left", "fill_right":
return true
default:
return false
}
}
// IsBinaryOpCmp returns true if op is comparison operator such as '==', '!=', etc.
func IsBinaryOpCmp(op string) bool {
switch op {

View File

@@ -39,6 +39,9 @@ func canOptimize(e Expr) bool {
}
}
case *BinaryOpExpr:
if t.FillLeft != nil && t.FillRight != nil {
return canOptimize(t.Left) || canOptimize(t.Right)
}
return true
}
return false
@@ -66,8 +69,23 @@ func optimizeInplace(e Expr) {
case *BinaryOpExpr:
optimizeInplace(t.Left)
optimizeInplace(t.Right)
lfs := getCommonLabelFilters(t)
pushdownBinaryOpFiltersInplace(lfs, t)
switch {
case t.FillLeft != nil && t.FillRight != nil:
// for two-sided fill, no cross-side pushdown.
case t.FillLeft != nil:
// for fill_left(), only propagate filters from right to left.
lfs := getCommonLabelFilters(t.Right)
lfs = TrimFiltersByGroupModifier(lfs, t)
pushdownBinaryOpFiltersInplace(lfs, t.Left)
case t.FillRight != nil:
// for fill_right(), only propagate filters from left to right.
lfs := getCommonLabelFilters(t.Left)
lfs = TrimFiltersByGroupModifier(lfs, t)
pushdownBinaryOpFiltersInplace(lfs, t.Right)
default:
lfs := getCommonLabelFilters(t)
pushdownBinaryOpFiltersInplace(lfs, t)
}
}
}

View File

@@ -402,6 +402,15 @@ func (p *parser) parseExpr() (Expr, error) {
}
}
}
for {
ok, err := p.parseFillModifier(&be)
if err != nil {
return nil, err
}
if !ok {
break
}
}
e2, err := p.parseSingleExpr()
if err != nil {
return nil, err
@@ -506,6 +515,65 @@ func (p *parser) parseSingleExprWithoutRollupSuffix() (Expr, error) {
}
}
func (p *parser) parseFillModifier(be *BinaryOpExpr) (bool, error) {
if !isBinaryOpFillModifier(p.lex.Token) {
return false, nil
}
if isSetOperator(be.Op) {
return false, fmt.Errorf(`fill modifier cannot be applied to %q`, be.Op)
}
op := strings.ToLower(p.lex.Token)
if err := p.lex.Next(); err != nil {
return false, err
}
if p.lex.Token != "(" {
p.lex.Prev()
return false, nil
}
if err := p.lex.Next(); err != nil {
return false, err
}
ne, err := p.parseFillValue()
if err != nil {
return false, fmt.Errorf("cannot parse %s fill value: %w", op, err)
}
if p.lex.Token != ")" {
return false, fmt.Errorf(`%s: unexpected token %q; want ")"`, op, p.lex.Token)
}
if err := p.lex.Next(); err != nil {
return false, err
}
switch op {
case "fill":
be.FillLeft = ne
be.FillRight = ne
case "fill_left":
be.FillLeft = ne
case "fill_right":
be.FillRight = ne
}
return true, nil
}
func (p *parser) parseFillValue() (*NumberExpr, error) {
neg := false
if p.lex.Token == "-" {
neg = true
if err := p.lex.Next(); err != nil {
return nil, err
}
}
ne, err := p.parsePositiveNumberExpr()
if err != nil {
return nil, err
}
if neg {
ne.N = -ne.N
ne.s = "-" + ne.s
}
return ne, nil
}
func (p *parser) parsePositiveNumberExpr() (*NumberExpr, error) {
if !isPositiveNumberPrefix(p.lex.Token) && !isInfOrNaN(p.lex.Token) {
return nil, fmt.Errorf(`positiveNumberExpr: unexpected token %q; want "number"`, p.lex.Token)
@@ -1896,6 +1964,12 @@ type BinaryOpExpr struct {
// If KeepMetricNames is set to true, then the operation should keep metric names.
KeepMetricNames bool
// FillLeft contains the fill value for fill_left() or fill() modifier.
FillLeft *NumberExpr
// FillRight contains the fill value for fill_right() or fill() modifier.
FillRight *NumberExpr
// Left contains left arg for the `left op right` expression.
Left Expr
@@ -1971,6 +2045,22 @@ func (be *BinaryOpExpr) appendModifiers(dst []byte) []byte {
dst = prefix.AppendString(dst)
}
}
if be.FillLeft != nil && be.FillLeft == be.FillRight {
dst = append(dst, " fill("...)
dst = be.FillLeft.AppendString(dst)
dst = append(dst, ')')
} else {
if be.FillLeft != nil {
dst = append(dst, " fill_left("...)
dst = be.FillLeft.AppendString(dst)
dst = append(dst, ')')
}
if be.FillRight != nil {
dst = append(dst, " fill_right("...)
dst = be.FillRight.AppendString(dst)
dst = append(dst, ')')
}
}
return dst
}
@@ -1989,7 +2079,7 @@ func needBinaryOpArgParens(arg Expr) bool {
}
func isReservedBinaryOpIdent(s string) bool {
return isBinaryOpGroupModifier(s) || isBinaryOpJoinModifier(s) || isBinaryOpBoolModifier(s) || isPrefixModifier(s)
return isBinaryOpGroupModifier(s) || isBinaryOpJoinModifier(s) || isBinaryOpBoolModifier(s) || isPrefixModifier(s) || isBinaryOpFillModifier(s)
}
func isPrefixModifier(s string) bool {

62
vendor/golang.org/x/sys/cpu/parse.go generated vendored
View File

@@ -6,38 +6,50 @@ package cpu
import "strconv"
// parseRelease parses a dot-separated version number. It follows the semver
// syntax, but allows the minor and patch versions to be elided.
// parseRelease parses a dot-separated version number from the prefix
// of rel. It returns ok=true only if at least the major and minor
// components were successfully parsed; the patch component is
// best-effort. Trailing vendor or build suffixes such as
// "-generic", "+", "_hi3535", or "-rc1" are ignored.
//
// This is a copy of the Go runtime's parseRelease from
// https://golang.org/cl/209597.
// https://golang.org/cl/209597, updated in https://golang.org/cl/781800.
func parseRelease(rel string) (major, minor, patch int, ok bool) {
// Strip anything after a dash or plus.
for i := range len(rel) {
if rel[i] == '-' || rel[i] == '+' {
rel = rel[:i]
break
// next consumes a run of decimal digits from the front of rel,
// returning the parsed value. If the digits are followed by a
// '.', it is consumed and more is set so the caller knows to
// parse another component; otherwise scanning terminates and
// the rest of rel is discarded.
next := func() (n int, more, ok bool) {
i := 0
for i < len(rel) && rel[i] >= '0' && rel[i] <= '9' {
i++
}
if i == 0 {
return 0, false, false
}
n, err := strconv.Atoi(rel[:i])
if err != nil {
return 0, false, false
}
if i < len(rel) && rel[i] == '.' {
rel = rel[i+1:]
return n, true, true
}
rel = ""
return n, false, true
}
next := func() (int, bool) {
for i := range len(rel) {
if rel[i] == '.' {
ver, err := strconv.Atoi(rel[:i])
rel = rel[i+1:]
return ver, err == nil
}
}
ver, err := strconv.Atoi(rel)
rel = ""
return ver, err == nil
var more bool
if major, more, ok = next(); !ok || !more {
return 0, 0, 0, false
}
if major, ok = next(); !ok || rel == "" {
return
if minor, more, ok = next(); !ok {
return 0, 0, 0, false
}
if minor, ok = next(); !ok || rel == "" {
return
if !more {
return major, minor, 0, true
}
patch, ok = next()
return
patch, _, _ = next()
return major, minor, patch, true
}

View File

@@ -1874,6 +1874,7 @@ func Dup2(oldfd, newfd int) error {
//sys Dup3(oldfd int, newfd int, flags int) (err error)
//sysnb EpollCreate1(flag int) (fd int, err error)
//sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
//sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2
//sys Exit(code int) = SYS_EXIT_GROUP
//sys Fallocate(fd int, mode uint32, off int64, len int64) (err error)

View File

@@ -20,7 +20,6 @@ func setTimeval(sec, usec int64) Timeval {
// 64-bit file system and 32-bit uid calls
// (386 default is 32-bit file system and 16-bit uid).
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64

View File

@@ -6,7 +6,6 @@
package unix
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error)

View File

@@ -44,7 +44,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
// 64-bit file system and 32-bit uid calls
// (16-bit uid calls are not always supported in newer kernels)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64

View File

@@ -8,7 +8,6 @@ package unix
import "unsafe"
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error)

View File

@@ -8,7 +8,6 @@ package unix
import "unsafe"
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstatfs(fd int, buf *Statfs_t) (err error)

View File

@@ -6,7 +6,6 @@
package unix
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstatfs(fd int, buf *Statfs_t) (err error)

View File

@@ -13,7 +13,6 @@ import (
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64

View File

@@ -11,7 +11,6 @@ import (
"unsafe"
)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64

View File

@@ -6,7 +6,6 @@
package unix
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error)

View File

@@ -8,7 +8,6 @@ package unix
import "unsafe"
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error)

View File

@@ -10,7 +10,6 @@ import (
"unsafe"
)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error)

View File

@@ -6,7 +6,6 @@
package unix
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error)

View File

@@ -1359,6 +1359,7 @@ const (
FAN_UNLIMITED_MARKS = 0x20
FAN_UNLIMITED_QUEUE = 0x10
FD_CLOEXEC = 0x1
FD_PIDFS_ROOT = -0x2712
FD_SETSIZE = 0x400
FF0 = 0x0
FIB_RULE_DEV_DETACHED = 0x8
@@ -1970,6 +1971,8 @@ const (
MADV_DONTNEED = 0x4
MADV_DONTNEED_LOCKED = 0x18
MADV_FREE = 0x8
MADV_GUARD_INSTALL = 0x66
MADV_GUARD_REMOVE = 0x67
MADV_HUGEPAGE = 0xe
MADV_HWPOISON = 0x64
MADV_KEEPONFORK = 0x13
@@ -2114,7 +2117,7 @@ const (
MS_NOSEC = 0x10000000
MS_NOSUID = 0x2
MS_NOSYMFOLLOW = 0x100
MS_NOUSER = -0x80000000
MS_NOUSER = 0x80000000
MS_POSIXACL = 0x10000
MS_PRIVATE = 0x40000
MS_RDONLY = 0x1
@@ -3786,6 +3789,9 @@ const (
TCPOPT_TIMESTAMP = 0x8
TCPOPT_TSTAMP_HDR = 0x101080a
TCPOPT_WINDOW = 0x3
TCP_AO_KEYF_EXCLUDE_OPT = 0x2
TCP_AO_KEYF_IFINDEX = 0x1
TCP_AO_MAXKEYLEN = 0x50
TCP_CC_INFO = 0x1a
TCP_CM_INQ = 0x24
TCP_CONGESTION = 0xd

View File

@@ -700,6 +700,23 @@ func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_PWAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Eventfd(initval uint, flags int) (fd int, err error) {
r0, _, e1 := Syscall(SYS_EVENTFD2, uintptr(initval), uintptr(flags), 0)
fd = int(r0)

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
_, _, e1 := Syscall6(SYS_FADVISE64_64, uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(length), uintptr(length>>32), uintptr(advice))
if e1 != 0 {

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
_, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0)
if e1 != 0 {

View File

@@ -213,23 +213,6 @@ func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fchown(fd int, uid int, gid int) (err error) {
_, _, e1 := Syscall(SYS_FCHOWN32, uintptr(fd), uintptr(uid), uintptr(gid))
if e1 != 0 {

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_PWAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
_, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0)
if e1 != 0 {

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_PWAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
_, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0)
if e1 != 0 {

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
_, _, e1 := Syscall9(SYS_FADVISE64, uintptr(fd), 0, uintptr(offset>>32), uintptr(offset), uintptr(length>>32), uintptr(length), uintptr(advice), 0, 0)
if e1 != 0 {

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
_, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0)
if e1 != 0 {

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
_, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0)
if e1 != 0 {

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
_, _, e1 := Syscall9(SYS_FADVISE64, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(length), uintptr(length>>32), uintptr(advice), 0, 0)
if e1 != 0 {

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fchown(fd int, uid int, gid int) (err error) {
_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
if e1 != 0 {

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
_, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0)
if e1 != 0 {

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
_, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0)
if e1 != 0 {

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_PWAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
_, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0)
if e1 != 0 {

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
_, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0)
if e1 != 0 {

View File

@@ -45,23 +45,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
var _p0 unsafe.Pointer
if len(events) > 0 {
_p0 = unsafe.Pointer(&events[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
_, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0)
if e1 != 0 {

View File

@@ -1109,17 +1109,53 @@ const (
)
// This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
//
// Go pointers stored in a TrusteeValue must be pinned using [runtime.Pinner]
// for the lifetime of the TrusteeValue.
type TrusteeValue uintptr
// TrusteeValueFromString is unsafe and should not be used.
//
// It returns a uintptr containing a reference to newly-allocated memory
// which will be freed by the garbage collector.
// There is no way for the caller to safely reference this memory.
//
// To create a [TrusteeValue] from a string, use:
//
// p, err := windows.UTF16PtrFromString(s)
// if err != nil {
// // handle error
// }
//
// // Pin the string for as long as it is used.
// var pinner runtime.Pinner
// pinner.Pin(p)
// defer pinner.Unpin()
//
// tv := TrusteeValue(unsafe.Pointer(p))
//
// Deprecated: TrusteeValueFromString is unsafe and should not be used.
func TrusteeValueFromString(str string) TrusteeValue {
return TrusteeValue(unsafe.Pointer(StringToUTF16Ptr(str)))
}
// TrusteeValueFromSID returns a [TrusteeValue] referencing sid.
//
// The caller must pin sid using a [runtime.Pinner] for the lifetime of the TrusteeValue.
func TrusteeValueFromSID(sid *SID) TrusteeValue {
return TrusteeValue(unsafe.Pointer(sid))
}
// TrusteeValueFromObjectsAndSid returns a [TrusteeValue] referencing objectsAndSid.
//
// The caller must pin objectsAndSid using a [runtime.Pinner] for the lifetime of the TrusteeValue.
func TrusteeValueFromObjectsAndSid(objectsAndSid *OBJECTS_AND_SID) TrusteeValue {
return TrusteeValue(unsafe.Pointer(objectsAndSid))
}
// TrusteeValueFromObjectsAndName returns a [TrusteeValue] referencing objectsAndName.
//
// The caller must pin objectsAndName using a [runtime.Pinner] for the lifetime of the TrusteeValue.
func TrusteeValueFromObjectsAndName(objectsAndName *OBJECTS_AND_NAME) TrusteeValue {
return TrusteeValue(unsafe.Pointer(objectsAndName))
}

View File

@@ -1728,11 +1728,15 @@ func (s *NTUnicodeString) String() string {
// the more common *uint16 string type.
func NewNTString(s string) (*NTString, error) {
var nts NTString
s8, err := BytePtrFromString(s)
s8, err := ByteSliceFromString(s)
if err != nil {
return nil, err
}
RtlInitString(&nts, s8)
// The source string plus its terminating NUL must fit within MAX_USHORT.
if len(s8) > MAX_USHORT {
return nil, syscall.EINVAL
}
RtlInitString(&nts, &s8[0])
return &nts, nil
}

View File

@@ -169,6 +169,7 @@ const (
FORMAT_MESSAGE_ARGUMENT_ARRAY = 8192
FORMAT_MESSAGE_MAX_WIDTH_MASK = 255
MAX_USHORT = 0xffff
MAX_PATH = 260
MAX_LONG_PATH = 32768

4
vendor/modules.txt vendored
View File

@@ -146,7 +146,7 @@ github.com/VictoriaMetrics/fastcache
# github.com/VictoriaMetrics/metrics v1.44.0
## explicit; go 1.24.0
github.com/VictoriaMetrics/metrics
# github.com/VictoriaMetrics/metricsql v0.87.2
# github.com/VictoriaMetrics/metricsql v0.87.3
## explicit; go 1.24.2
github.com/VictoriaMetrics/metricsql
github.com/VictoriaMetrics/metricsql/binaryop
@@ -902,7 +902,7 @@ golang.org/x/oauth2/jwt
## explicit; go 1.25.0
golang.org/x/sync/errgroup
golang.org/x/sync/semaphore
# golang.org/x/sys v0.46.0
# golang.org/x/sys v0.47.0
## explicit; go 1.25.0
golang.org/x/sys/cpu
golang.org/x/sys/plan9