blob: 2395a2e7c3afd0e8d184fba8d9c1dfe9c119c459 [file] [log] [blame]
Patrick Venture4dc584d2018-09-27 15:00:46 -07001#include "utils.hpp"
2
3#include <dlfcn.h>
4
Patrick Venture6c415c62018-11-14 14:01:36 -08005#include <blobs-ipmid/manager.hpp>
Patrick Venture4dc584d2018-09-27 15:00:46 -07006#include <experimental/filesystem>
Patrick Venture6c415c62018-11-14 14:01:36 -08007#include <memory>
Patrick Venture4dc584d2018-09-27 15:00:46 -07008#include <phosphor-logging/log.hpp>
9#include <regex>
10
11namespace blobs
12{
13
14namespace fs = std::experimental::filesystem;
15using namespace phosphor::logging;
16
Patrick Venture6c415c62018-11-14 14:01:36 -080017using HandlerFactory = std::unique_ptr<GenericBlobInterface> (*)();
18
Patrick Venture4dc584d2018-09-27 15:00:46 -070019void loadLibraries(const std::string& path)
20{
21 void* libHandle = NULL;
Patrick Venture6c415c62018-11-14 14:01:36 -080022 HandlerFactory factory;
23 auto* manager = getBlobManager();
Patrick Venture4dc584d2018-09-27 15:00:46 -070024
25 for (const auto& p : fs::recursive_directory_iterator(path))
26 {
27 auto ps = p.path().string();
28
Patrick Venture1d5cccb2018-11-13 13:08:03 -080029 /* The bitbake recipe symlinks the library lib*.so.? into the folder
30 * only, and not the other names, .so, .so.?.?, .so.?.?.?
31 *
32 * Therefore only care if it's lib*.so.?
33 */
34 if (!std::regex_match(ps, std::regex(".+\\.so\\.\\d+$")))
Patrick Venture4dc584d2018-09-27 15:00:46 -070035 {
36 continue;
37 }
38
Patrick Venture6c415c62018-11-14 14:01:36 -080039 libHandle = dlopen(ps.c_str(), RTLD_NOW | RTLD_GLOBAL);
Patrick Venture4dc584d2018-09-27 15:00:46 -070040 if (!libHandle)
41 {
42 log<level::ERR>("ERROR opening", entry("HANDLER=%s", ps.c_str()),
43 entry("ERROR=%s", dlerror()));
Patrick Venture6c415c62018-11-14 14:01:36 -080044 continue;
Patrick Venture4dc584d2018-09-27 15:00:46 -070045 }
Patrick Venture6c415c62018-11-14 14:01:36 -080046
47 dlerror(); /* Clear any previous error. */
48
49 factory =
50 reinterpret_cast<HandlerFactory>(dlsym(libHandle, "createHandler"));
51
52 const char* error = dlerror();
53 if (error)
54 {
55 log<level::ERR>("ERROR loading symbol",
56 entry("HANDLER=%s", ps.c_str()),
57 entry("ERROR=%s", error));
58 continue;
59 }
60
61 std::unique_ptr<GenericBlobInterface> result = factory();
62 if (!result)
63 {
64 log<level::ERR>("Unable to create handler",
65 entry("HANDLER=%s", ps.c_str()));
66 continue;
67 }
68
69 manager->registerHandler(std::move(result));
Patrick Venture4dc584d2018-09-27 15:00:46 -070070 }
71}
72
73} // namespace blobs