From a484a83d4ae1bc76db37cd750742a5b6df65982d Mon Sep 17 00:00:00 2001 From: Sunil Thaha Date: Wed, 17 Nov 2021 21:09:04 +1000 Subject: [PATCH] fix: panic when checkpoint directory is empty (#9687) Calling `wal.NewSegmentBufReader()` without any segments would cause a `panic` resulting in prometheus crashing. This patch fixes the panic by making segmentBufReader return a EOF if there are not segments. This also means an empty checkpoint directory which should never be the case unless it has been tampered with (or has issues due to the underlying filesystem e.g. NFS) would be ignored by Prometheus and would continue to run instead of the current behaviour which is to panic. Fixes: https://github.com/prometheus/prometheus/issues/9605 Signed-off-by: Sunil Thaha --- tsdb/wal/wal.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tsdb/wal/wal.go b/tsdb/wal/wal.go index a38dfdab2..3bc2894d3 100644 --- a/tsdb/wal/wal.go +++ b/tsdb/wal/wal.go @@ -878,6 +878,10 @@ type segmentBufReader struct { // nolint:revive // TODO: Consider exporting segmentBufReader func NewSegmentBufReader(segs ...*Segment) *segmentBufReader { + if len(segs) == 0 { + return &segmentBufReader{} + } + return &segmentBufReader{ buf: bufio.NewReaderSize(segs[0], 16*pageSize), segs: segs, @@ -886,9 +890,10 @@ func NewSegmentBufReader(segs ...*Segment) *segmentBufReader { // nolint:revive func NewSegmentBufReaderWithOffset(offset int, segs ...*Segment) (sbr *segmentBufReader, err error) { - if offset == 0 { + if offset == 0 || len(segs) == 0 { return NewSegmentBufReader(segs...), nil } + sbr = &segmentBufReader{ buf: bufio.NewReaderSize(segs[0], 16*pageSize), segs: segs, @@ -910,6 +915,10 @@ func (r *segmentBufReader) Close() (err error) { // Read implements io.Reader. func (r *segmentBufReader) Read(b []byte) (n int, err error) { + if len(r.segs) == 0 { + return 0, io.EOF + } + n, err = r.buf.Read(b) r.off += n