From 7a4928643d0d92bc75ebcb3603b56b5883c49d7c Mon Sep 17 00:00:00 2001 From: Alessandro Ros Date: Mon, 20 Mar 2023 23:01:47 +0100 Subject: [PATCH] restore compatibility with non-raspberry arm systems (#1587) --- internal/core/core.go | 11 +-- internal/rpicamera/libcamera.go | 51 ------------ internal/rpicamera/libcamera_disabled.go | 13 --- internal/rpicamera/rpicamera.go | 102 ++++++++++++++++++----- internal/rpicamera/rpicamera_disabled.go | 4 + 5 files changed, 91 insertions(+), 90 deletions(-) delete mode 100644 internal/rpicamera/libcamera.go delete mode 100644 internal/rpicamera/libcamera_disabled.go diff --git a/internal/core/core.go b/internal/core/core.go index f8fefc15..af3c9e3c 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -181,8 +181,6 @@ outer: p.ctxCancel() p.closeResources(nil, false) - - rpicamera.LibcameraCleanup() } func (p *Core) createResources(initial bool) error { @@ -210,11 +208,6 @@ func (p *Core) createResources(initial bool) error { // do not check for errors rlimit.Raise() - err := rpicamera.LibcameraSetup() - if err != nil { - return err - } - gin.SetMode(gin.ReleaseMode) p.externalCmdPool = externalcmd.NewPool() @@ -679,6 +672,10 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) { p.externalCmdPool.Close() } + if newConf == nil { + rpicamera.Cleanup() + } + if closeLogger { p.logger.Close() p.logger = nil diff --git a/internal/rpicamera/libcamera.go b/internal/rpicamera/libcamera.go deleted file mode 100644 index 9e31f330..00000000 --- a/internal/rpicamera/libcamera.go +++ /dev/null @@ -1,51 +0,0 @@ -//go:build rpicamera -// +build rpicamera - -package rpicamera - -import ( - "fmt" - "os" - "os/exec" - "strings" -) - -func findLibrary(name string) (string, error) { - byts, err := exec.Command("ldconfig", "-p").Output() - if err == nil { - for _, line := range strings.Split(string(byts), "\n") { - f := strings.Split(line, " => ") - if len(f) == 2 && strings.Contains(f[1], name+".so") { - return f[1], nil - } - } - } - - return "", fmt.Errorf("library '%s' not found", name) -} - -func setupSymlink(name string) error { - lib, err := findLibrary(name) - if err != nil { - return err - } - - os.Remove("/dev/shm/" + name + ".so.x.x.x") - return os.Symlink(lib, "/dev/shm/"+name+".so.x.x.x") -} - -// LibcameraSetup creates libcamera simlinks that are version agnostic. -func LibcameraSetup() error { - err := setupSymlink("libcamera") - if err != nil { - return err - } - - return setupSymlink("libcamera-base") -} - -// LibcameraCleanup removes files created by LibcameraSetup. -func LibcameraCleanup() { - os.Remove("/dev/shm/libcamera-base.so.x.x.x") - os.Remove("/dev/shm/libcamera.so.x.x.x") -} diff --git a/internal/rpicamera/libcamera_disabled.go b/internal/rpicamera/libcamera_disabled.go deleted file mode 100644 index ad54b1c9..00000000 --- a/internal/rpicamera/libcamera_disabled.go +++ /dev/null @@ -1,13 +0,0 @@ -//go:build !rpicamera -// +build !rpicamera - -package rpicamera - -// LibcameraSetup creates libcamera simlinks that are version agnostic. -func LibcameraSetup() error { - return nil -} - -// LibcameraCleanup removes files created by LibcameraSetup. -func LibcameraCleanup() { -} diff --git a/internal/rpicamera/rpicamera.go b/internal/rpicamera/rpicamera.go index 88f04e62..3daa59f0 100644 --- a/internal/rpicamera/rpicamera.go +++ b/internal/rpicamera/rpicamera.go @@ -12,6 +12,7 @@ import ( "runtime" "strconv" "strings" + "sync" "time" "github.com/aler9/gortsplib/v2/pkg/codecs/h264" @@ -35,24 +36,6 @@ func getKernelArch() (string, error) { return string(byts[:len(byts)-1]), nil } -// 32-bit embedded executables can't run on 64-bit. -func checkArch() error { - if runtime.GOARCH != "arm" { - return nil - } - - arch, err := getKernelArch() - if err != nil { - return err - } - - if arch == "aarch64" { - return fmt.Errorf("OS is 64-bit, you need the arm64 server version") - } - - return nil -} - func startEmbeddedExe(content []byte, env []string) (*exec.Cmd, error) { tempPath := tempPathPrefix + strconv.FormatInt(time.Now().UnixNano(), 10) @@ -113,6 +96,87 @@ func serializeParams(p Params) []byte { return []byte(strings.Join(ret, " ")) } +func findLibrary(name string) (string, error) { + byts, err := exec.Command("ldconfig", "-p").Output() + if err == nil { + for _, line := range strings.Split(string(byts), "\n") { + f := strings.Split(line, " => ") + if len(f) == 2 && strings.Contains(f[1], name+".so") { + return f[1], nil + } + } + } + + return "", fmt.Errorf("library '%s' not found", name) +} + +func setupSymlink(name string) error { + lib, err := findLibrary(name) + if err != nil { + return err + } + + os.Remove("/dev/shm/" + name + ".so.x.x.x") + return os.Symlink(lib, "/dev/shm/"+name+".so.x.x.x") +} + +// 32-bit embedded executables can't run on 64-bit. +func checkArch() error { + if runtime.GOARCH != "arm" { + return nil + } + + arch, err := getKernelArch() + if err != nil { + return err + } + + if arch == "aarch64" { + return fmt.Errorf("OS is 64-bit, you need the arm64 server version") + } + + return nil +} + +var ( + mutex sync.Mutex + setupped bool +) + +func setupLibcameraOnce() error { + mutex.Lock() + defer mutex.Unlock() + + if !setupped { + err := checkArch() + if err != nil { + return err + } + + err = setupSymlink("libcamera") + if err != nil { + return err + } + + err = setupSymlink("libcamera-base") + if err != nil { + return err + } + + setupped = true + } + + return nil +} + +// Cleanup cleanups files created by the camera implementation. +func Cleanup() { + if setupped { + os.Remove("/dev/shm/libcamera-base.so.x.x.x") + os.Remove("/dev/shm/libcamera.so.x.x.x") + } +} + type RPICamera struct { onData func(time.Duration, [][]byte) @@ -128,7 +192,7 @@ func New( params Params, onData func(time.Duration, [][]byte), ) (*RPICamera, error) { - err := checkArch() + err := setupLibcameraOnce() if err != nil { return nil, err } diff --git a/internal/rpicamera/rpicamera_disabled.go b/internal/rpicamera/rpicamera_disabled.go index 499ddf9a..baa02c83 100644 --- a/internal/rpicamera/rpicamera_disabled.go +++ b/internal/rpicamera/rpicamera_disabled.go @@ -9,6 +9,10 @@ import ( "time" ) +// Cleanup cleanups files created by the camera implementation. +func Cleanup() { +} + // RPICamera is a RPI Camera reader. type RPICamera struct{}