blob: d0a5e5e10ce6beb5afe764be795a39227ef5b6a4 [file] [log] [blame]
Patrick Venturec0fe5cd2018-11-21 14:10:26 -08001/*
2 * Copyright 2018 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Patrick Venture4dc584d2018-09-27 15:00:46 -070017#include "utils.hpp"
18
Patrick Venturec18e2b62018-11-21 14:19:28 -080019#include "fs.hpp"
Patrick Venturecd8dab42019-01-15 19:57:38 -080020#include "manager.hpp"
Patrick Venturec18e2b62018-11-21 14:19:28 -080021
Patrick Venture4dc584d2018-09-27 15:00:46 -070022#include <dlfcn.h>
23
Patrick Venture6c415c62018-11-14 14:01:36 -080024#include <memory>
Patrick Venture4dc584d2018-09-27 15:00:46 -070025#include <phosphor-logging/log.hpp>
26#include <regex>
Patrick Venturec18e2b62018-11-21 14:19:28 -080027#include <string>
William A. Kennington III766beb32021-06-16 11:47:51 -070028#include <unordered_set>
Patrick Venturec18e2b62018-11-21 14:19:28 -080029#include <vector>
Patrick Venture4dc584d2018-09-27 15:00:46 -070030
31namespace blobs
32{
33
Patrick Venture4dc584d2018-09-27 15:00:46 -070034using namespace phosphor::logging;
35
Patrick Venturec18e2b62018-11-21 14:19:28 -080036bool matchBlobHandler(const std::string& filename)
37{
William A. Kennington III3ccee072021-06-15 16:51:30 -070038 return filename.find(".so") != std::string::npos;
Patrick Venturec18e2b62018-11-21 14:19:28 -080039}
Patrick Venture6c415c62018-11-14 14:01:36 -080040
Patrick Venturec18e2b62018-11-21 14:19:28 -080041void loadLibraries(ManagerInterface* manager, const std::string& path,
42 const internal::DlSysInterface* sys)
Patrick Venture4dc584d2018-09-27 15:00:46 -070043{
William A. Kennington III766beb32021-06-16 11:47:51 -070044 std::unordered_set<HandlerFactory> seen;
Patrick Venture4dc584d2018-09-27 15:00:46 -070045 void* libHandle = NULL;
Patrick Venture6c415c62018-11-14 14:01:36 -080046 HandlerFactory factory;
Patrick Venture4dc584d2018-09-27 15:00:46 -070047
Patrick Venturec18e2b62018-11-21 14:19:28 -080048 std::vector<std::string> libs = getLibraryList(path, matchBlobHandler);
49
50 for (const auto& p : libs)
Patrick Venture4dc584d2018-09-27 15:00:46 -070051 {
Patrick Venturec18e2b62018-11-21 14:19:28 -080052 libHandle = sys->dlopen(p.c_str(), RTLD_NOW | RTLD_GLOBAL);
Patrick Venture4dc584d2018-09-27 15:00:46 -070053 if (!libHandle)
54 {
Patrick Venturec18e2b62018-11-21 14:19:28 -080055 log<level::ERR>("ERROR opening", entry("HANDLER=%s", p.c_str()),
56 entry("ERROR=%s", sys->dlerror()));
Patrick Venture6c415c62018-11-14 14:01:36 -080057 continue;
Patrick Venture4dc584d2018-09-27 15:00:46 -070058 }
Patrick Venture6c415c62018-11-14 14:01:36 -080059
Patrick Venturec18e2b62018-11-21 14:19:28 -080060 sys->dlerror(); /* Clear any previous error. */
Patrick Venture6c415c62018-11-14 14:01:36 -080061
Patrick Venturec18e2b62018-11-21 14:19:28 -080062 factory = reinterpret_cast<HandlerFactory>(
63 sys->dlsym(libHandle, "createHandler"));
Patrick Venture6c415c62018-11-14 14:01:36 -080064
Patrick Venturec18e2b62018-11-21 14:19:28 -080065 const char* error = sys->dlerror();
Patrick Venture6c415c62018-11-14 14:01:36 -080066 if (error)
67 {
68 log<level::ERR>("ERROR loading symbol",
Patrick Venturec18e2b62018-11-21 14:19:28 -080069 entry("HANDLER=%s", p.c_str()),
Patrick Venture6c415c62018-11-14 14:01:36 -080070 entry("ERROR=%s", error));
71 continue;
72 }
73
William A. Kennington III766beb32021-06-16 11:47:51 -070074 // We may have duplicate libraries in the blobs directory that we only
75 // want to initialize once.
76 if (seen.count(factory) > 0)
77 {
78 continue;
79 }
80 seen.emplace(factory);
81
Patrick Venturec7c941d2020-12-08 12:10:37 -080082 try
Patrick Venture6c415c62018-11-14 14:01:36 -080083 {
Patrick Venturec7c941d2020-12-08 12:10:37 -080084 std::unique_ptr<GenericBlobInterface> result = factory();
85 if (!result)
86 {
87 log<level::ERR>("Unable to create handler",
88 entry("HANDLER=%s", p.c_str()));
89 continue;
90 }
Patrick Venture6c415c62018-11-14 14:01:36 -080091
Patrick Venturec7c941d2020-12-08 12:10:37 -080092 manager->registerHandler(std::move(result));
93 }
94 catch (const std::exception& e)
95 {
96 log<level::ERR>("Received exception loading handler",
97 entry("HANDLER=%s", p.c_str()),
98 entry("EXCEPTION=%s", e.what()));
99 }
Patrick Venture4dc584d2018-09-27 15:00:46 -0700100 }
101}
102
103} // namespace blobs