[libcamera-devel] [RFC PATCH 10/10] libcamera: ipa: shim: load IPA module into an IPAInterface
Paul Elder
paul.elder at ideasonboard.com
Thu Jun 6 00:18:17 CEST 2019
Implement the dummy shim's init method that takes a path for the IPA
module to be loaded. Set up IPC, then fork and load the IPAInterface
implementation from the IPA module shared object.
Implement a cleanup method along with it.
Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
---
This is the most draft-y patch of the whole series. I wasn't sure how to
put what kind of IPC, so I kind of just did this very skeletal "give you
an idea" type of IPC initialization. Privilege dropping will be looked
into for the next version.
src/ipa/shim_dummy.cpp | 79 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 77 insertions(+), 2 deletions(-)
diff --git a/src/ipa/shim_dummy.cpp b/src/ipa/shim_dummy.cpp
index 4d28c2d..f2e6961 100644
--- a/src/ipa/shim_dummy.cpp
+++ b/src/ipa/shim_dummy.cpp
@@ -6,6 +6,14 @@
*/
#include <iostream>
+#include <memory>
+
+#include <dlfcn.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <libcamera/ipa/ipa_interface.h>
#include <libcamera/ipa/ipa_module_info.h>
@@ -17,20 +25,87 @@ class ShimDummy : public IPAInterface
public:
int init();
int init(const char *path);
+
+ void cleanup();
+
+private:
+ std::unique_ptr<IPAInterface> ipa_;
+
+ int sockets_[2];
+ int childPid_;
+ void *dlHandle_;
+
+ typedef IPAInterface *(*IPAIntfFactory)(void);
};
int ShimDummy::init()
{
- std::cout << "okay shim init without path" << std::endl;
+ std::cout << "initializing IPA via dummy shim!" << std::endl;
return 0;
}
int ShimDummy::init(const char *path)
{
- std::cout << "initializing dummy shim!" << std::endl;
+ std::cout << "initializing dummy shim! loading IPA from " << path
+ << std::endl;
+
+ /* We know the IPA module is valid, otherwise IPAManager wouldn't
+ * even give its path to us. */
+
+ // setup comm
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets_)) {
+ int err = errno;
+ std::cerr << "Error opening sockets: " << strerror(errno)
+ << std::endl;
+ return err;
+ }
+
+ // fork
+ if ((childPid_ = fork()) == -1) {
+ int err = errno;
+ std::cerr << "Failed to fork: " << strerror(errno) << std::endl;
+ return err;
+ } else if (childPid_) {
+ // we are parent
+ // we can read/write sockets_[1]
+ close(sockets_[0]);
+ } else {
+ // we are child
+ // we can read/write sockets_[0]
+ close(sockets_[1]);
+
+ dlHandle_ = dlopen(path, RTLD_LAZY);
+ if (!dlHandle_) {
+ std::cerr << "Failed to open IPA module: "
+ << dlerror() << std::endl;
+ return -1;
+ }
+
+ void *symbol = dlsym(dlHandle_, "ipaCreate");
+ if (!symbol) {
+ std::cerr
+ << "Failed to load ipaCreate() from IPA module shared object: "
+ << dlerror();
+ dlclose(dlHandle_);
+ dlHandle_ = nullptr;
+ return -1;
+ }
+
+ IPAIntfFactory ipaCreate = reinterpret_cast<IPAIntfFactory>(symbol);
+ ipa_ = std::unique_ptr<IPAInterface>(ipaCreate());
+ exit(0);
+ }
+
return 0;
}
+void ShimDummy::cleanup()
+{
+ if (dlHandle_)
+ dlclose(dlHandle_);
+ dlHandle_ = nullptr;
+}
+
/*
* External IPA module interface
*/
--
2.20.1
More information about the libcamera-devel
mailing list