libpod/lock: Fix build and tests for SHM locks on FreeBSD

On FreeBSD, the path argument to shm_open is not a filesystem path and we
must use shm_unlink to remove it. This changes the Linux build to also use
shm_unlink which avoids assuming that shared memory segments live in
/dev/shm.

Signed-off-by: Doug Rabson <dfr@rabson.org>
This commit is contained in:
Doug Rabson
2022-11-08 11:20:11 +00:00
parent 1c79b01f6b
commit 978c528500
2 changed files with 29 additions and 8 deletions

View File

@ -1,11 +1,15 @@
//go:build linux && cgo
// +build linux,cgo
//go:build (linux || freebsd) && cgo
// +build linux freebsd
// +build cgo
package shm
// #cgo LDFLAGS: -lrt -lpthread
// #cgo CFLAGS: -Wall -Werror
// #include <stdlib.h>
// #include <sys/types.h>
// #include <sys/mman.h>
// #include <fcntl.h>
// #include "shm_lock.h"
// const uint32_t bitmap_size_c = BITMAP_SIZE;
import "C"
@ -261,3 +265,13 @@ func (locks *SHMLocks) UnlockSemaphore(sem uint32) error {
return nil
}
func unlinkSHMLock(path string) error {
cPath := C.CString(path)
defer C.free(unsafe.Pointer(cPath))
if _, err := C.shm_unlink(cPath); err != nil {
return fmt.Errorf("failed to unlink SHM locks: %w", err)
}
return nil
}

View File

@ -1,10 +1,12 @@
//go:build linux
// +build linux
//go:build linux || freebsd
// +build linux freebsd
package shm
import (
"errors"
"fmt"
"io/fs"
"os"
"runtime"
"testing"
@ -28,8 +30,11 @@ const lockPath = "/libpod_test"
// We need a test main to ensure that the SHM is created before the tests run
func TestMain(m *testing.M) {
// Remove prior /dev/shm/libpod_test
os.RemoveAll("/dev/shm" + lockPath)
// Remove prior /libpod_test
if err := unlinkSHMLock(lockPath); err != nil && !errors.Is(err, fs.ErrNotExist) {
fmt.Fprintf(os.Stderr, "Error cleaning SHM for tests: %v\n", err)
os.Exit(-1)
}
shmLock, err := CreateSHMLock(lockPath, numLocks)
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating SHM for tests: %v\n", err)
@ -76,8 +81,10 @@ func runLockTest(t *testing.T, testFunc func(*testing.T, *SHMLocks)) {
// Test that creating an SHM with a bad size rounds up to a good size
func TestCreateNewSHMBadSizeRoundsUp(t *testing.T) {
// Remove prior /dev/shm/test1
os.RemoveAll("/dev/shm/test1")
// Remove prior /test1
if err := unlinkSHMLock("/test1"); err != nil && !errors.Is(err, fs.ErrNotExist) {
t.Fatalf("Error cleaning SHM for tests: %v\n", err)
}
// Odd number, not a power of 2, should never be a word size on a system
lock, err := CreateSHMLock("/test1", 7)
assert.NoError(t, err)