Skip to content

Commit

Permalink
map: define new ErrMapMismatch error
Browse files Browse the repository at this point in the history
This error will be returned by NewMapWithOptions whether the spec for a
pinned map is incompatible with the actual instance of the map, in order
to allow the caller to properly detect this mismatch.

Fixes #289

Signed-off-by: Gilberto Bertin <gilberto@isovalent.com>
  • Loading branch information
jibi authored and lmb committed Apr 21, 2021
1 parent 89b0b27 commit a4ee356
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
15 changes: 9 additions & 6 deletions map.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var (
ErrKeyNotExist = errors.New("key does not exist")
ErrKeyExist = errors.New("key already exists")
ErrIterationAborted = errors.New("iteration aborted")
ErrMapIncompatible = errors.New("map's spec is incompatible with pinned map")
)

// MapOptions control loading a map into the kernel.
Expand Down Expand Up @@ -96,19 +97,19 @@ type MapKV struct {
func (ms *MapSpec) checkCompatibility(m *Map) error {
switch {
case m.typ != ms.Type:
return fmt.Errorf("expected type %v, got %v", ms.Type, m.typ)
return fmt.Errorf("expected type %v, got %v: %w", ms.Type, m.typ, ErrMapIncompatible)

case m.keySize != ms.KeySize:
return fmt.Errorf("expected key size %v, got %v", ms.KeySize, m.keySize)
return fmt.Errorf("expected key size %v, got %v: %w", ms.KeySize, m.keySize, ErrMapIncompatible)

case m.valueSize != ms.ValueSize:
return fmt.Errorf("expected value size %v, got %v", ms.ValueSize, m.valueSize)
return fmt.Errorf("expected value size %v, got %v: %w", ms.ValueSize, m.valueSize, ErrMapIncompatible)

case m.maxEntries != ms.MaxEntries:
return fmt.Errorf("expected max entries %v, got %v", ms.MaxEntries, m.maxEntries)
return fmt.Errorf("expected max entries %v, got %v: %w", ms.MaxEntries, m.maxEntries, ErrMapIncompatible)

case m.flags != ms.Flags:
return fmt.Errorf("expected flags %v, got %v", ms.Flags, m.flags)
return fmt.Errorf("expected flags %v, got %v: %w", ms.Flags, m.flags, ErrMapIncompatible)
}
return nil
}
Expand Down Expand Up @@ -171,6 +172,8 @@ func NewMap(spec *MapSpec) (*Map, error) {
// The caller is responsible for ensuring the process' rlimit is set
// sufficiently high for locking memory during map creation. This can be done
// by calling unix.Setrlimit with unix.RLIMIT_MEMLOCK prior to calling NewMapWithOptions.
//
// May return an error wrapping ErrMapIncompatible.
func NewMapWithOptions(spec *MapSpec, opts MapOptions) (*Map, error) {
handles := newHandleCache()
defer handles.close()
Expand Down Expand Up @@ -202,7 +205,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_
defer closeOnError(m)

if err := spec.checkCompatibility(m); err != nil {
return nil, fmt.Errorf("use pinned map %s: %s", spec.Name, err)
return nil, fmt.Errorf("use pinned map %s: %w", spec.Name, err)
}

return m, nil
Expand Down
10 changes: 10 additions & 0 deletions map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1315,6 +1315,16 @@ func TestMapPinning(t *testing.T) {
if value != 42 {
t.Fatal("Pinning doesn't use pinned maps")
}

spec.KeySize = 8
m3, err := NewMapWithOptions(spec, MapOptions{PinPath: tmp})
if err == nil {
m3.Close()
t.Fatalf("Opening a pinned map with a mismatching spec did not fail")
}
if !errors.Is(err, ErrMapIncompatible) {
t.Fatalf("Opening a pinned map with a mismatching spec failed with the wrong error")
}
}

type benchValue struct {
Expand Down

0 comments on commit a4ee356

Please sign in to comment.