build(deps): bump github.com/containerd/cgroups/v3 from 3.0.2 to 3.0.3
Bumps [github.com/containerd/cgroups/v3](https://github.com/containerd/cgroups) from 3.0.2 to 3.0.3. - [Release notes](https://github.com/containerd/cgroups/releases) - [Commits](https://github.com/containerd/cgroups/compare/v3.0.2...v3.0.3) --- updated-dependencies: - dependency-name: github.com/containerd/cgroups/v3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
206
vendor/github.com/cilium/ebpf/map.go
generated
vendored
206
vendor/github.com/cilium/ebpf/map.go
generated
vendored
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"time"
|
||||
@@ -77,9 +78,6 @@ type MapSpec struct {
|
||||
|
||||
// The key and value type of this map. May be nil.
|
||||
Key, Value btf.Type
|
||||
|
||||
// The BTF associated with this map.
|
||||
BTF *btf.Spec
|
||||
}
|
||||
|
||||
func (ms *MapSpec) String() string {
|
||||
@@ -104,12 +102,6 @@ func (ms *MapSpec) Copy() *MapSpec {
|
||||
return &cpy
|
||||
}
|
||||
|
||||
// hasBTF returns true if the MapSpec has a valid BTF spec and if its
|
||||
// map type supports associated BTF metadata in the kernel.
|
||||
func (ms *MapSpec) hasBTF() bool {
|
||||
return ms.BTF != nil && ms.Type.hasBTF()
|
||||
}
|
||||
|
||||
func (ms *MapSpec) clampPerfEventArraySize() error {
|
||||
if ms.Type != PerfEventArray {
|
||||
return nil
|
||||
@@ -158,7 +150,11 @@ type MapKV struct {
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
func (ms *MapSpec) checkCompatibility(m *Map) error {
|
||||
// Compatible returns nil if an existing map may be used instead of creating
|
||||
// one from the spec.
|
||||
//
|
||||
// Returns an error wrapping [ErrMapIncompatible] otherwise.
|
||||
func (ms *MapSpec) Compatible(m *Map) error {
|
||||
switch {
|
||||
case m.typ != ms.Type:
|
||||
return fmt.Errorf("expected type %v, got %v: %w", ms.Type, m.typ, ErrMapIncompatible)
|
||||
@@ -173,7 +169,10 @@ func (ms *MapSpec) checkCompatibility(m *Map) error {
|
||||
m.maxEntries != ms.MaxEntries:
|
||||
return fmt.Errorf("expected max entries %v, got %v: %w", ms.MaxEntries, m.maxEntries, ErrMapIncompatible)
|
||||
|
||||
case m.flags != ms.Flags:
|
||||
// BPF_F_RDONLY_PROG is set unconditionally for devmaps. Explicitly allow
|
||||
// this mismatch.
|
||||
case !((ms.Type == DevMap || ms.Type == DevMapHash) && m.flags^ms.Flags == unix.BPF_F_RDONLY_PROG) &&
|
||||
m.flags != ms.Flags:
|
||||
return fmt.Errorf("expected flags %v, got %v: %w", ms.Flags, m.flags, ErrMapIncompatible)
|
||||
}
|
||||
return nil
|
||||
@@ -241,10 +240,7 @@ func NewMap(spec *MapSpec) (*Map, error) {
|
||||
//
|
||||
// May return an error wrapping ErrMapIncompatible.
|
||||
func NewMapWithOptions(spec *MapSpec, opts MapOptions) (*Map, error) {
|
||||
handles := newHandleCache()
|
||||
defer handles.close()
|
||||
|
||||
m, err := newMapWithOptions(spec, opts, handles)
|
||||
m, err := newMapWithOptions(spec, opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating map: %w", err)
|
||||
}
|
||||
@@ -257,7 +253,7 @@ func NewMapWithOptions(spec *MapSpec, opts MapOptions) (*Map, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_ *Map, err error) {
|
||||
func newMapWithOptions(spec *MapSpec, opts MapOptions) (_ *Map, err error) {
|
||||
closeOnError := func(c io.Closer) {
|
||||
if err != nil {
|
||||
c.Close()
|
||||
@@ -284,7 +280,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_
|
||||
}
|
||||
defer closeOnError(m)
|
||||
|
||||
if err := spec.checkCompatibility(m); err != nil {
|
||||
if err := spec.Compatible(m); err != nil {
|
||||
return nil, fmt.Errorf("use pinned map %s: %w", spec.Name, err)
|
||||
}
|
||||
|
||||
@@ -307,7 +303,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_
|
||||
return nil, errors.New("inner maps cannot be pinned")
|
||||
}
|
||||
|
||||
template, err := spec.InnerMap.createMap(nil, opts, handles)
|
||||
template, err := spec.InnerMap.createMap(nil, opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("inner map: %w", err)
|
||||
}
|
||||
@@ -319,7 +315,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_
|
||||
innerFd = template.fd
|
||||
}
|
||||
|
||||
m, err := spec.createMap(innerFd, opts, handles)
|
||||
m, err := spec.createMap(innerFd, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -328,7 +324,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_
|
||||
if spec.Pinning == PinByName {
|
||||
path := filepath.Join(opts.PinPath, spec.Name)
|
||||
if err := m.Pin(path); err != nil {
|
||||
return nil, fmt.Errorf("pin map: %w", err)
|
||||
return nil, fmt.Errorf("pin map to %s: %w", path, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,15 +333,13 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_
|
||||
|
||||
// createMap validates the spec's properties and creates the map in the kernel
|
||||
// using the given opts. It does not populate or freeze the map.
|
||||
func (spec *MapSpec) createMap(inner *sys.FD, opts MapOptions, handles *handleCache) (_ *Map, err error) {
|
||||
func (spec *MapSpec) createMap(inner *sys.FD, opts MapOptions) (_ *Map, err error) {
|
||||
closeOnError := func(closer io.Closer) {
|
||||
if err != nil {
|
||||
closer.Close()
|
||||
}
|
||||
}
|
||||
|
||||
spec = spec.Copy()
|
||||
|
||||
// Kernels 4.13 through 5.4 used a struct bpf_map_def that contained
|
||||
// additional 'inner_map_idx' and later 'numa_node' fields.
|
||||
// In order to support loading these definitions, tolerate the presence of
|
||||
@@ -365,17 +359,21 @@ func (spec *MapSpec) createMap(inner *sys.FD, opts MapOptions, handles *handleCa
|
||||
if spec.ValueSize != 0 && spec.ValueSize != 4 {
|
||||
return nil, errors.New("ValueSize must be zero or four for map of map")
|
||||
}
|
||||
|
||||
spec = spec.Copy()
|
||||
spec.ValueSize = 4
|
||||
|
||||
case PerfEventArray:
|
||||
if spec.KeySize != 0 && spec.KeySize != 4 {
|
||||
return nil, errors.New("KeySize must be zero or four for perf event array")
|
||||
}
|
||||
spec.KeySize = 4
|
||||
|
||||
if spec.ValueSize != 0 && spec.ValueSize != 4 {
|
||||
return nil, errors.New("ValueSize must be zero or four for perf event array")
|
||||
}
|
||||
|
||||
spec = spec.Copy()
|
||||
spec.KeySize = 4
|
||||
spec.ValueSize = 4
|
||||
|
||||
if spec.MaxEntries == 0 {
|
||||
@@ -413,7 +411,7 @@ func (spec *MapSpec) createMap(inner *sys.FD, opts MapOptions, handles *handleCa
|
||||
KeySize: spec.KeySize,
|
||||
ValueSize: spec.ValueSize,
|
||||
MaxEntries: spec.MaxEntries,
|
||||
MapFlags: spec.Flags,
|
||||
MapFlags: sys.MapFlags(spec.Flags),
|
||||
NumaNode: spec.NumaNode,
|
||||
}
|
||||
|
||||
@@ -425,40 +423,43 @@ func (spec *MapSpec) createMap(inner *sys.FD, opts MapOptions, handles *handleCa
|
||||
attr.MapName = sys.NewObjName(spec.Name)
|
||||
}
|
||||
|
||||
if spec.hasBTF() {
|
||||
handle, err := handles.btfHandle(spec.BTF)
|
||||
if spec.Key != nil || spec.Value != nil {
|
||||
handle, keyTypeID, valueTypeID, err := btf.MarshalMapKV(spec.Key, spec.Value)
|
||||
if err != nil && !errors.Is(err, btf.ErrNotSupported) {
|
||||
return nil, fmt.Errorf("load BTF: %w", err)
|
||||
}
|
||||
|
||||
if handle != nil {
|
||||
keyTypeID, err := spec.BTF.TypeID(spec.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
valueTypeID, err := spec.BTF.TypeID(spec.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer handle.Close()
|
||||
|
||||
// Use BTF k/v during map creation.
|
||||
attr.BtfFd = uint32(handle.FD())
|
||||
attr.BtfKeyTypeId = uint32(keyTypeID)
|
||||
attr.BtfValueTypeId = uint32(valueTypeID)
|
||||
attr.BtfKeyTypeId = keyTypeID
|
||||
attr.BtfValueTypeId = valueTypeID
|
||||
}
|
||||
}
|
||||
|
||||
fd, err := sys.MapCreate(&attr)
|
||||
// Some map types don't support BTF k/v in earlier kernel versions.
|
||||
// Remove BTF metadata and retry map creation.
|
||||
if (errors.Is(err, sys.ENOTSUPP) || errors.Is(err, unix.EINVAL)) && attr.BtfFd != 0 {
|
||||
attr.BtfFd, attr.BtfKeyTypeId, attr.BtfValueTypeId = 0, 0, 0
|
||||
fd, err = sys.MapCreate(&attr)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, unix.EPERM) {
|
||||
return nil, fmt.Errorf("map create: %w (MEMLOCK may be too low, consider rlimit.RemoveMemlock)", err)
|
||||
}
|
||||
if !spec.hasBTF() {
|
||||
return nil, fmt.Errorf("map create without BTF: %w", err)
|
||||
}
|
||||
if errors.Is(err, unix.EINVAL) && attr.MaxEntries == 0 {
|
||||
return nil, fmt.Errorf("map create: %w (MaxEntries may be incorrectly set to zero)", err)
|
||||
}
|
||||
if errors.Is(err, unix.EINVAL) && spec.Type == UnspecifiedMap {
|
||||
return nil, fmt.Errorf("map create: cannot use type %s", UnspecifiedMap)
|
||||
}
|
||||
if attr.BtfFd == 0 {
|
||||
return nil, fmt.Errorf("map create: %w (without BTF k/v)", err)
|
||||
}
|
||||
return nil, fmt.Errorf("map create: %w", err)
|
||||
}
|
||||
defer closeOnError(fd)
|
||||
@@ -495,7 +496,7 @@ func newMap(fd *sys.FD, name string, typ MapType, keySize, valueSize, maxEntries
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m.fullValueSize = internal.Align(int(valueSize), 8) * possibleCPUs
|
||||
m.fullValueSize = int(internal.Align(valueSize, 8)) * possibleCPUs
|
||||
return m, nil
|
||||
}
|
||||
|
||||
@@ -549,12 +550,7 @@ const LookupLock MapLookupFlags = 4
|
||||
//
|
||||
// Returns an error if the key doesn't exist, see ErrKeyNotExist.
|
||||
func (m *Map) Lookup(key, valueOut interface{}) error {
|
||||
valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize)
|
||||
if err := m.lookup(key, valuePtr, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return m.unmarshalValue(valueOut, valueBytes)
|
||||
return m.LookupWithFlags(key, valueOut, 0)
|
||||
}
|
||||
|
||||
// LookupWithFlags retrieves a value from a Map with flags.
|
||||
@@ -568,6 +564,10 @@ func (m *Map) Lookup(key, valueOut interface{}) error {
|
||||
//
|
||||
// Returns an error if the key doesn't exist, see ErrKeyNotExist.
|
||||
func (m *Map) LookupWithFlags(key, valueOut interface{}, flags MapLookupFlags) error {
|
||||
if m.typ.hasPerCPUValue() {
|
||||
return m.lookupPerCPU(key, valueOut, flags)
|
||||
}
|
||||
|
||||
valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize)
|
||||
if err := m.lookup(key, valuePtr, flags); err != nil {
|
||||
return err
|
||||
@@ -580,7 +580,7 @@ func (m *Map) LookupWithFlags(key, valueOut interface{}, flags MapLookupFlags) e
|
||||
//
|
||||
// Returns ErrKeyNotExist if the key doesn't exist.
|
||||
func (m *Map) LookupAndDelete(key, valueOut interface{}) error {
|
||||
return m.lookupAndDelete(key, valueOut, 0)
|
||||
return m.LookupAndDeleteWithFlags(key, valueOut, 0)
|
||||
}
|
||||
|
||||
// LookupAndDeleteWithFlags retrieves and deletes a value from a Map.
|
||||
@@ -591,7 +591,15 @@ func (m *Map) LookupAndDelete(key, valueOut interface{}) error {
|
||||
//
|
||||
// Returns ErrKeyNotExist if the key doesn't exist.
|
||||
func (m *Map) LookupAndDeleteWithFlags(key, valueOut interface{}, flags MapLookupFlags) error {
|
||||
return m.lookupAndDelete(key, valueOut, flags)
|
||||
if m.typ.hasPerCPUValue() {
|
||||
return m.lookupAndDeletePerCPU(key, valueOut, flags)
|
||||
}
|
||||
|
||||
valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize)
|
||||
if err := m.lookupAndDelete(key, valuePtr, flags); err != nil {
|
||||
return err
|
||||
}
|
||||
return m.unmarshalValue(valueOut, valueBytes)
|
||||
}
|
||||
|
||||
// LookupBytes gets a value from Map.
|
||||
@@ -609,6 +617,14 @@ func (m *Map) LookupBytes(key interface{}) ([]byte, error) {
|
||||
return valueBytes, err
|
||||
}
|
||||
|
||||
func (m *Map) lookupPerCPU(key, valueOut any, flags MapLookupFlags) error {
|
||||
valueBytes := make([]byte, m.fullValueSize)
|
||||
if err := m.lookup(key, sys.NewSlicePointer(valueBytes), flags); err != nil {
|
||||
return err
|
||||
}
|
||||
return unmarshalPerCPUValue(valueOut, int(m.valueSize), valueBytes)
|
||||
}
|
||||
|
||||
func (m *Map) lookup(key interface{}, valueOut sys.Pointer, flags MapLookupFlags) error {
|
||||
keyPtr, err := m.marshalKey(key)
|
||||
if err != nil {
|
||||
@@ -628,9 +644,15 @@ func (m *Map) lookup(key interface{}, valueOut sys.Pointer, flags MapLookupFlags
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Map) lookupAndDelete(key, valueOut interface{}, flags MapLookupFlags) error {
|
||||
valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize)
|
||||
func (m *Map) lookupAndDeletePerCPU(key, valueOut any, flags MapLookupFlags) error {
|
||||
valueBytes := make([]byte, m.fullValueSize)
|
||||
if err := m.lookupAndDelete(key, sys.NewSlicePointer(valueBytes), flags); err != nil {
|
||||
return err
|
||||
}
|
||||
return unmarshalPerCPUValue(valueOut, int(m.valueSize), valueBytes)
|
||||
}
|
||||
|
||||
func (m *Map) lookupAndDelete(key any, valuePtr sys.Pointer, flags MapLookupFlags) error {
|
||||
keyPtr, err := m.marshalKey(key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't marshal key: %w", err)
|
||||
@@ -647,7 +669,7 @@ func (m *Map) lookupAndDelete(key, valueOut interface{}, flags MapLookupFlags) e
|
||||
return fmt.Errorf("lookup and delete: %w", wrapMapError(err))
|
||||
}
|
||||
|
||||
return m.unmarshalValue(valueOut, valueBytes)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MapUpdateFlags controls the behaviour of the Map.Update call.
|
||||
@@ -674,15 +696,32 @@ func (m *Map) Put(key, value interface{}) error {
|
||||
}
|
||||
|
||||
// Update changes the value of a key.
|
||||
func (m *Map) Update(key, value interface{}, flags MapUpdateFlags) error {
|
||||
keyPtr, err := m.marshalKey(key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't marshal key: %w", err)
|
||||
func (m *Map) Update(key, value any, flags MapUpdateFlags) error {
|
||||
if m.typ.hasPerCPUValue() {
|
||||
return m.updatePerCPU(key, value, flags)
|
||||
}
|
||||
|
||||
valuePtr, err := m.marshalValue(value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't marshal value: %w", err)
|
||||
return fmt.Errorf("marshal value: %w", err)
|
||||
}
|
||||
|
||||
return m.update(key, valuePtr, flags)
|
||||
}
|
||||
|
||||
func (m *Map) updatePerCPU(key, value any, flags MapUpdateFlags) error {
|
||||
valuePtr, err := marshalPerCPUValue(value, int(m.valueSize))
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshal value: %w", err)
|
||||
}
|
||||
|
||||
return m.update(key, valuePtr, flags)
|
||||
}
|
||||
|
||||
func (m *Map) update(key any, valuePtr sys.Pointer, flags MapUpdateFlags) error {
|
||||
keyPtr, err := m.marshalKey(key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshal key: %w", err)
|
||||
}
|
||||
|
||||
attr := sys.MapUpdateElemAttr{
|
||||
@@ -798,12 +837,22 @@ func (m *Map) nextKey(key interface{}, nextKeyOut sys.Pointer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var mmapProtectedPage = internal.Memoize(func() ([]byte, error) {
|
||||
return unix.Mmap(-1, 0, os.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_SHARED)
|
||||
})
|
||||
|
||||
// guessNonExistentKey attempts to perform a map lookup that returns ENOENT.
|
||||
// This is necessary on kernels before 4.4.132, since those don't support
|
||||
// iterating maps from the start by providing an invalid key pointer.
|
||||
func (m *Map) guessNonExistentKey() ([]byte, error) {
|
||||
// Provide an invalid value pointer to prevent a copy on the kernel side.
|
||||
valuePtr := sys.NewPointer(unsafe.Pointer(^uintptr(0)))
|
||||
// Map a protected page and use that as the value pointer. This saves some
|
||||
// work copying out the value, which we're not interested in.
|
||||
page, err := mmapProtectedPage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
valuePtr := sys.NewSlicePointer(page)
|
||||
|
||||
randKey := make([]byte, int(m.keySize))
|
||||
|
||||
for i := 0; i < 4; i++ {
|
||||
@@ -1095,7 +1144,8 @@ func (m *Map) Clone() (*Map, error) {
|
||||
// the new path already exists. Re-pinning across filesystems is not supported.
|
||||
// You can Clone a map to pin it to a different path.
|
||||
//
|
||||
// This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs
|
||||
// This requires bpffs to be mounted above fileName.
|
||||
// See https://docs.cilium.io/en/stable/network/kubernetes/configuration/#mounting-bpffs-with-systemd
|
||||
func (m *Map) Pin(fileName string) error {
|
||||
if err := internal.Pin(m.pinnedPath, fileName, m.fd); err != nil {
|
||||
return err
|
||||
@@ -1180,10 +1230,6 @@ func (m *Map) unmarshalKey(data interface{}, buf []byte) error {
|
||||
}
|
||||
|
||||
func (m *Map) marshalValue(data interface{}) (sys.Pointer, error) {
|
||||
if m.typ.hasPerCPUValue() {
|
||||
return marshalPerCPUValue(data, int(m.valueSize))
|
||||
}
|
||||
|
||||
var (
|
||||
buf []byte
|
||||
err error
|
||||
@@ -1316,8 +1362,7 @@ func marshalMap(m *Map, length int) ([]byte, error) {
|
||||
// See Map.Iterate.
|
||||
type MapIterator struct {
|
||||
target *Map
|
||||
prevKey interface{}
|
||||
prevBytes []byte
|
||||
curKey []byte
|
||||
count, maxEntries uint32
|
||||
done bool
|
||||
err error
|
||||
@@ -1327,7 +1372,6 @@ func newMapIterator(target *Map) *MapIterator {
|
||||
return &MapIterator{
|
||||
target: target,
|
||||
maxEntries: target.maxEntries,
|
||||
prevBytes: make([]byte, target.keySize),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1349,26 +1393,35 @@ func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool {
|
||||
// For array-like maps NextKeyBytes returns nil only on after maxEntries
|
||||
// iterations.
|
||||
for mi.count <= mi.maxEntries {
|
||||
var nextBytes []byte
|
||||
nextBytes, mi.err = mi.target.NextKeyBytes(mi.prevKey)
|
||||
var nextKey []byte
|
||||
if mi.curKey == nil {
|
||||
// Pass nil interface to NextKeyBytes to make sure the Map's first key
|
||||
// is returned. If we pass an uninitialized []byte instead, it'll see a
|
||||
// non-nil interface and try to marshal it.
|
||||
nextKey, mi.err = mi.target.NextKeyBytes(nil)
|
||||
|
||||
mi.curKey = make([]byte, mi.target.keySize)
|
||||
} else {
|
||||
nextKey, mi.err = mi.target.NextKeyBytes(mi.curKey)
|
||||
}
|
||||
if mi.err != nil {
|
||||
mi.err = fmt.Errorf("get next key: %w", mi.err)
|
||||
return false
|
||||
}
|
||||
|
||||
if nextBytes == nil {
|
||||
if nextKey == nil {
|
||||
mi.done = true
|
||||
return false
|
||||
}
|
||||
|
||||
// The user can get access to nextBytes since unmarshalBytes
|
||||
// The user can get access to nextKey since unmarshalBytes
|
||||
// does not copy when unmarshaling into a []byte.
|
||||
// Make a copy to prevent accidental corruption of
|
||||
// iterator state.
|
||||
copy(mi.prevBytes, nextBytes)
|
||||
mi.prevKey = mi.prevBytes
|
||||
copy(mi.curKey, nextKey)
|
||||
|
||||
mi.count++
|
||||
mi.err = mi.target.Lookup(nextBytes, valueOut)
|
||||
mi.err = mi.target.Lookup(nextKey, valueOut)
|
||||
if errors.Is(mi.err, ErrKeyNotExist) {
|
||||
// Even though the key should be valid, we couldn't look up
|
||||
// its value. If we're iterating a hash map this is probably
|
||||
@@ -1381,10 +1434,11 @@ func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool {
|
||||
continue
|
||||
}
|
||||
if mi.err != nil {
|
||||
mi.err = fmt.Errorf("look up next key: %w", mi.err)
|
||||
return false
|
||||
}
|
||||
|
||||
mi.err = mi.target.unmarshalKey(keyOut, nextBytes)
|
||||
mi.err = mi.target.unmarshalKey(keyOut, nextKey)
|
||||
return mi.err == nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user