From db87efa2ec1e91e81517236b164b279e57b8daa8 Mon Sep 17 00:00:00 2001 From: Ondrej Fabry Date: Fri, 20 Mar 2020 10:52:19 +0100 Subject: Fix statsclient for VPP 20.05-rc0 (master) - this change fixes panic that was occurring with recent VPP that was caused by incorrectly calculated vector length - converting returned vector length from uint64 to uint32 results in correct length value Change-Id: I76a4b9d147c3df3bea9d3e5ef5853e2809dc42e8 Signed-off-by: Ondrej Fabry --- adapter/statsclient/statsclient.go | 61 ++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 29 deletions(-) (limited to 'adapter/statsclient/statsclient.go') diff --git a/adapter/statsclient/statsclient.go b/adapter/statsclient/statsclient.go index d4e5a56..9110275 100644 --- a/adapter/statsclient/statsclient.go +++ b/adapter/statsclient/statsclient.go @@ -121,12 +121,24 @@ func (c *StatsClient) ListStats(patterns ...string) (names []string, err error) if err != nil { return nil, err } + + dirVector := c.getStatDirVector() + vecLen := uint32(vectorLen(dirVector)) + for _, index := range indexes { - name, err := c.entryName(index) - if err != nil { - return nil, err + if index >= vecLen { + return nil, fmt.Errorf("stat entry index %d out of dir vector len (%d)", index, vecLen) } - names = append(names, name) + + dirEntry := c.getStatDirIndex(dirVector, index) + var name []byte + for n := 0; n < len(dirEntry.name); n++ { + if dirEntry.name[n] == 0 { + name = dirEntry.name[:n] + break + } + } + names = append(names, string(name)) } if !c.accessEnd(&sa) { @@ -142,11 +154,11 @@ func (c *StatsClient) DumpStats(patterns ...string) (entries []adapter.StatEntry return nil, adapter.ErrStatsAccessFailed } - dir, err := c.listIndexes(patterns...) + indexes, err := c.listIndexes(patterns...) if err != nil { return nil, err } - if entries, err = c.dumpEntries(dir); err != nil { + if entries, err = c.dumpEntries(indexes); err != nil { return nil, err } @@ -261,7 +273,7 @@ func (c *StatsClient) listIndexes(patterns ...string) (indexes []uint32, err err func (c *StatsClient) listIndexesFunc(f func(name []byte) bool) (indexes []uint32, err error) { if f == nil { - // there is around ~3150 stats, so to avoid too many allocations + // there is around ~3157 stats, so to avoid too many allocations // we set capacity to 3200 when listing all stats indexes = make([]uint32, 0, 3200) } @@ -290,33 +302,18 @@ func (c *StatsClient) listIndexesFunc(f func(name []byte) bool) (indexes []uint3 return indexes, nil } -func (c *StatsClient) entryName(index uint32) (string, error) { +func (c *StatsClient) dumpEntries(indexes []uint32) (entries []adapter.StatEntry, err error) { dirVector := c.getStatDirVector() - vecLen := uint32(vectorLen(dirVector)) + dirLen := uint32(vectorLen(dirVector)) - if index >= vecLen { - return "", fmt.Errorf("stat entry index %d out of range (%d)", index, vecLen) - } - - dirEntry := c.getStatDirIndex(dirVector, index) - - var name []byte - for n := 0; n < len(dirEntry.name); n++ { - if dirEntry.name[n] == 0 { - name = dirEntry.name[:n] - break - } - } - - return string(name), nil -} + debugf("dumping entres for %d indexes", len(indexes)) -func (c *StatsClient) dumpEntries(indexes []uint32) (entries []adapter.StatEntry, err error) { entries = make([]adapter.StatEntry, 0, len(indexes)) - - dirVector := c.getStatDirVector() - for _, index := range indexes { + if index >= dirLen { + return nil, fmt.Errorf("stat entry index %d out of dir vector length (%d)", index, dirLen) + } + dirEntry := c.getStatDirIndex(dirVector, index) var name []byte @@ -326,6 +323,12 @@ func (c *StatsClient) dumpEntries(indexes []uint32) (entries []adapter.StatEntry break } } + + if Debug { + debugf(" - %3d. dir: %q type: %v offset: %d union: %d", index, name, + adapter.StatType(dirEntry.directoryType), dirEntry.offsetVector, dirEntry.unionData) + } + if len(name) == 0 { continue } -- cgit 1.2.3-korg