From e2e1bf600af7f6f772f03ba33d19b3e89c9c50dc Mon Sep 17 00:00:00 2001 From: Ivan Schasny <31857042+ischasny@users.noreply.github.com> Date: Mon, 15 Jan 2024 13:47:03 +0000 Subject: [PATCH] fix: fallback to regular indexing if podsi failed (#1870) --- piecedirectory/piecedirectory.go | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/piecedirectory/piecedirectory.go b/piecedirectory/piecedirectory.go index 45b6b31bd..22c2fb77d 100644 --- a/piecedirectory/piecedirectory.go +++ b/piecedirectory/piecedirectory.go @@ -406,14 +406,6 @@ func (cr *countingReader) Read(p []byte) (n int, err error) { } func parsePieceWithDataSegmentIndex(pieceCid cid.Cid, unpaddedSize int64, r types.SectionReader) ([]model.Record, error) { - defer func() { - // This is a temporary workaround to handle "slice bounds out of range" errors in podsi indexing. - // The bug affects a minor number of deals, so recovering here will help to unblock the users. - // TODO: remove this recover when the underlying bug is figured out and fixed. - if err := recover(); err != nil { - log.Errorw("Recovered from panic and skipped indexing the piece.", "piece", pieceCid, "error", err) - } - }() concurrency := runtime.NumCPU() if concurrency < PodsiMinConcurrency { @@ -437,10 +429,14 @@ func parsePieceWithDataSegmentIndex(pieceCid cid.Cid, unpaddedSize int64, r type Reader: r, cnt: &readsCnt, } - indexData, err := datasegment.ParseDataSegmentIndex(bufio.NewReaderSize(cr, PodsiBuffesrSize)) + panicked := false + indexData, err := parseDataSegmentIndex(pieceCid, bufio.NewReaderSize(cr, PodsiBuffesrSize), &panicked) if err != nil { return nil, fmt.Errorf("could not parse data segment index: %w", err) } + if panicked { + return nil, fmt.Errorf("could not parse data segment index because of an internal panic") + } log.Debugw("podsi: parsed data segment index", "segments", len(indexData.Entries), "reads", readsCnt, "time", time.Since(start).String()) @@ -523,6 +519,21 @@ func parsePieceWithDataSegmentIndex(pieceCid cid.Cid, unpaddedSize int64, r type return recs, nil } +// parseDataSegmentIndex is a temporary wrapper around datasegment.ParseDataSegmentIndex that exists only as a workaround +// for "slice bounds out of range" panic inside lotus. This funciton should be removed once the panic is fixed. +func parseDataSegmentIndex(pieceCid cid.Cid, unpaddedReader io.Reader, panicked *bool) (datasegment.IndexData, error) { + defer func() { + // This is a temporary workaround to handle "slice bounds out of range" errors in podsi indexing. + // The bug affects a minor number of deals, so recovering here will help to unblock the users. + // TODO: remove this recover when the underlying bug is figured out and fixed. + if err := recover(); err != nil { + *panicked = true + log.Errorw("Recovered from panic and skipped indexing the piece.", "piece", pieceCid, "error", err) + } + }() + return datasegment.ParseDataSegmentIndex(unpaddedReader) +} + func validateEntries(entries []datasegment.SegmentDesc) ([]datasegment.SegmentDesc, error) { res := make([]datasegment.SegmentDesc, 0, len(entries)) for i, e := range entries {