Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "lib_path.h"
12 : #include "mmpa_api.h"
13 : #include "log/hdc_log.h"
14 : #include "log/adx_log.h"
15 : #include "file_utils.h"
16 :
17 : namespace Adx {
18 : constexpr char LIBSUFFIX[] = ".so";
19 :
20 54 : LibPath& LibPath::Instance()
21 : {
22 54 : static LibPath libPath;
23 54 : return libPath;
24 : }
25 :
26 3 : Path LibPath::GetInstallParentPath() const
27 : {
28 : // get install path from self path : <install path>/x86_64-linux/lib64/ --> <install path>/x86_64-linux
29 3 : Path currentPath(LibPath::GetSelfLibraryDir());
30 3 : auto installPath = currentPath.ParentPath();
31 3 : return installPath;
32 3 : }
33 :
34 26 : Path LibPath::GetInstallPath() const
35 : {
36 : // get install path: <install path>/x86_64-linux/lib64/
37 26 : Path currentPath(LibPath::GetSelfLibraryDir());
38 26 : return currentPath;
39 : }
40 :
41 : /**
42 : * @brief Get directory path where self dynamic library in
43 : * @return Path
44 : */
45 29 : Path LibPath::GetSelfLibraryDir() const
46 : {
47 : mmDlInfo info;
48 29 : LibPath& (*instancePtr)() = &LibPath::Instance;
49 29 : const auto ret = mmDladdr(reinterpret_cast<void*>(instancePtr), &info);
50 29 : if (ret != EN_OK) {
51 0 : IDE_LOGE("Cannot find symbol GetSelfLibraryDir");
52 0 : return Path();
53 : }
54 29 : IDE_LOGD("Find symbol GetSelfLibraryDir in %s", info.dli_fname);
55 29 : Path path(info.dli_fname); // entire so name
56 29 : const auto name = path.GetFileName();
57 58 : if (name.length() <= strlen(LIBSUFFIX) ||
58 29 : name.compare(name.length() - strlen(LIBSUFFIX), strlen(LIBSUFFIX), LIBSUFFIX) != 0) {
59 29 : path = GetSelfPath();
60 : }
61 :
62 29 : if (!path.RealPath()) {
63 0 : IDE_LOGW("Can not get realpath self library path %s.", path.GetCString());
64 0 : return Path();
65 : }
66 :
67 29 : IDE_LOGI("Get self library path: %s", path.GetCString());
68 :
69 29 : return path.ParentPath();
70 29 : }
71 :
72 : /**
73 : * @brief Get directory path where self binary
74 : * @return Path
75 : */
76 29 : Path LibPath::GetSelfPath() const
77 : {
78 29 : Path selfPath;
79 29 : char curPath[MMPA_MAX_PATH + 1] = {0};
80 29 : const auto len = readlink("/proc/self/exe", curPath, MMPA_MAX_PATH);
81 29 : if (len <= 0 || len > MMPA_MAX_PATH) {
82 0 : IDE_LOGE("Get self path failed.");
83 0 : return selfPath;
84 : }
85 29 : curPath[len] = '\0';
86 :
87 29 : selfPath = curPath;
88 29 : IDE_LOGI("Get self path: %s", selfPath.GetCString());
89 29 : return selfPath;
90 0 : }
91 :
92 26 : std::string LibPath::GetTargetPath(const std::string& concatName) const
93 : {
94 26 : Path installBasePath = GetInstallPath();
95 26 : IDE_CTRL_VALUE_FAILED(!installBasePath.Empty(), return "", "Failed to get install path.");
96 26 : return installBasePath.Concat(concatName).GetString();
97 26 : }
98 :
99 4 : bool LibPath::IsPluginSo(const std::string& fileName) const
100 : {
101 8 : const std::string prefix = "adump_";
102 4 : const std::string suffix = "_plugin.so";
103 4 : if (fileName.size() < prefix.size() + suffix.size()) {
104 1 : return false;
105 : }
106 3 : if ((fileName.substr(0, prefix.size()) != prefix) || (fileName.substr(fileName.size() - suffix.size()) != suffix)) {
107 1 : return false;
108 : }
109 2 : return true;
110 4 : }
111 :
112 24 : std::vector<std::string> LibPath::ObtainAllPluginSo(const std::string& searchPath) const
113 : {
114 24 : std::vector<std::string> result;
115 24 : std::string realPath;
116 24 : IDE_CTRL_VALUE_WARN(
117 : FileUtils::FileNameIsReal(searchPath, realPath) == IDE_DAEMON_OK, return result,
118 : "Unable to get real path of %s and the search path is %s.", realPath.c_str(), searchPath.c_str());
119 1 : IDE_CTRL_VALUE_WARN(
120 : FileUtils::IsFileExist(realPath), return result, "Unable to find so from %s.", realPath.c_str());
121 :
122 1 : DIR* dir = opendir(realPath.c_str());
123 1 : IDE_CTRL_VALUE_WARN(dir, return result, "Unable to open dir %s with info %s.", realPath.c_str(), strerror(errno));
124 :
125 : struct dirent* entry;
126 8 : while ((entry = readdir(dir)) != nullptr) {
127 6 : if (entry->d_type == DT_REG) {
128 4 : std::string fileName = entry->d_name;
129 4 : if (IsPluginSo(fileName)) {
130 2 : result.push_back(realPath + "/" + fileName);
131 : }
132 4 : }
133 : }
134 1 : closedir(dir);
135 1 : return result;
136 24 : }
137 :
138 : } // namespace Adx
|