From 475675b16cb084a89dd78adbb372a9f27605d020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?U=C4=9Fur=20Tafral=C4=B1?= Date: Tue, 12 May 2026 18:11:47 +0300 Subject: [PATCH] lib/backup/fslocal: remove traling slash in provided directory (#10825) Trailing slash in -storageDataPath was causing vmrestore to panic. The fix calls filepath.Clean() in Init() to normalize the path. Added a test to verify ListParts works correctly with a trailing slash. Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10823 PR https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10825 --------- Signed-off-by: JAYICE Co-authored-by: Max Kotliar --- docs/victoriametrics/changelog/CHANGELOG.md | 1 + lib/backup/fslocal/fslocal.go | 1 + lib/backup/fslocal/fslocal_test.go | 30 +++++++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 lib/backup/fslocal/fslocal_test.go diff --git a/docs/victoriametrics/changelog/CHANGELOG.md b/docs/victoriametrics/changelog/CHANGELOG.md index 228530b2a0..56bd9a3d5f 100644 --- a/docs/victoriametrics/changelog/CHANGELOG.md +++ b/docs/victoriametrics/changelog/CHANGELOG.md @@ -31,6 +31,7 @@ See also [LTS releases](https://docs.victoriametrics.com/victoriametrics/lts-rel * BUGFIX: [stream aggregation](https://docs.victoriametrics.com/victoriametrics/stream-aggregation/): stop emitting stale values for `quantiles(...)` outputs when a time series has no samples during the current aggregation interval. Thanks to @alexei38 for the [pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10918). * BUGFIX: [stream aggregation](https://docs.victoriametrics.com/victoriametrics/stream-aggregation/): extend delay on aggregation windows flush by the biggest lag among pushed samples. Before, the delay was calculated as 95th percentile across samples, which could underrepresent outliers and reject them from aggregation as "too old". See [#10402](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10402). * BUGFIX: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/): fix a bug in [cardinality limiters](https://docs.victoriametrics.com/victoriametrics/vmagent/#cardinality-limiter) where series with different labels, like `{a="bc"}` and `{ab="c"}`, could be incorrectly treated as identical and dropped. See [#10937](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10937). +* BUGFIX: [vmrestore](https://docs.victoriametrics.com/victoriametrics/vmrestore/): fix a bug where specifying `-storageDataPath` with a trailing slash could cause `vmrestore` to panic. See [#10823](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10823). Thanks to @utafrali for the contribution. ## [v1.143.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.143.0) diff --git a/lib/backup/fslocal/fslocal.go b/lib/backup/fslocal/fslocal.go index f314ba7617..43d8eec791 100644 --- a/lib/backup/fslocal/fslocal.go +++ b/lib/backup/fslocal/fslocal.go @@ -33,6 +33,7 @@ type FS struct { // // The returned fs must be stopped when no long needed with MustStop call. func (fs *FS) Init() error { + fs.Dir = filepath.Clean(fs.Dir) if fs.MaxBytesPerSecond > 0 { fs.bl = newBandwidthLimiter(fs.MaxBytesPerSecond) } diff --git a/lib/backup/fslocal/fslocal_test.go b/lib/backup/fslocal/fslocal_test.go new file mode 100644 index 0000000000..80c7945b90 --- /dev/null +++ b/lib/backup/fslocal/fslocal_test.go @@ -0,0 +1,30 @@ +package fslocal + +import ( + "os" + "path/filepath" + "testing" +) + +func TestFSListPartsWithTrailingSlashInDir(t *testing.T) { + dir := t.TempDir() + if err := os.WriteFile(filepath.Join(dir, "testfile"), []byte("x"), 0600); err != nil { + t.Fatal(err) + } + + // trailing slash must not cause ListParts to panic + // See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10823 + fs := &FS{Dir: dir + string(filepath.Separator)} + if err := fs.Init(); err != nil { + t.Fatalf("Init error: %s", err) + } + defer fs.MustStop() + + parts, err := fs.ListParts() + if err != nil { + t.Fatalf("ListParts error: %s", err) + } + if len(parts) != 1 { + t.Fatalf("expected 1 part, got %d", len(parts)) + } +}