Skip to content

Commit d6f2c9f

Browse files
committed
Add linux driver discovery without lib load and handle single driver
Signed-off-by: Neil R. Spruit <neil.r.spruit@intel.com>
1 parent 5771e1a commit d6f2c9f

File tree

8 files changed

+576
-11
lines changed

8 files changed

+576
-11
lines changed

scripts/templates/ldrddi.cpp.mako

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -611,11 +611,20 @@ ${tbl['export']['name']}(
611611

612612
${x}_result_t result = ${X}_RESULT_SUCCESS;
613613

614+
%if namespace != "zes":
615+
auto driverCount = loader::context->zeDrivers.size();
616+
auto firstDriver = &loader::context->zeDrivers[0];
617+
%else:
618+
auto driverCount = loader::context->sysmanInstanceDrivers->size();
619+
auto firstDriver = &loader::context->sysmanInstanceDrivers->at(0);
620+
%endif
621+
if (driverCount == 1 && firstDriver && !loader::context->forceIntercept) {
622+
result = ${tbl['export']['name']}FromDriver(firstDriver);
623+
}
624+
614625
if( ${X}_RESULT_SUCCESS == result )
615626
{
616-
%if tbl['name'] == "Global":
617-
if( true )
618-
%elif namespace != "zes":
627+
%if namespace != "zes":
619628
if( ( loader::context->zeDrivers.size() > 1 ) || loader::context->forceIntercept )
620629
%elif namespace == "zes":
621630
if( ( loader::context->sysmanInstanceDrivers->size() > 1 ) || loader::context->forceIntercept )

source/loader/linux/driver_discovery_lin.cpp

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,90 @@
1313
#include <sstream>
1414
#include <string>
1515

16+
#include <dlfcn.h>
17+
#include <unistd.h>
18+
#include <dirent.h>
19+
20+
#include <vector>
21+
#include <fstream>
22+
#include <sys/stat.h>
23+
// Helper to split a colon-separated path string
24+
static std::vector<std::string> splitPaths(const std::string& paths) {
25+
std::vector<std::string> result;
26+
std::stringstream ss(paths);
27+
std::string item;
28+
while (std::getline(ss, item, ':')) {
29+
if (!item.empty()) result.push_back(item);
30+
}
31+
return result;
32+
}
33+
34+
// Helper to check if a file exists and is readable
35+
static bool fileExistsReadable(const std::string& path) {
36+
struct stat sb;
37+
return (stat(path.c_str(), &sb) == 0) && (access(path.c_str(), R_OK) == 0);
38+
}
39+
40+
// Helper to get all library search paths from LD_LIBRARY_PATH, standard locations, and /etc/ld.so.conf
41+
static std::vector<std::string> getLibrarySearchPaths() {
42+
std::vector<std::string> paths;
43+
// LD_LIBRARY_PATH
44+
const char* ldLibPath = getenv("LD_LIBRARY_PATH");
45+
if (ldLibPath) {
46+
auto split = splitPaths(ldLibPath);
47+
paths.insert(paths.end(), split.begin(), split.end());
48+
}
49+
// Standard locations
50+
paths.push_back("/lib");
51+
paths.push_back("/usr/lib");
52+
paths.push_back("/usr/local/lib");
53+
// /etc/ld.so.conf and included files
54+
std::ifstream ldSoConf("/etc/ld.so.conf");
55+
if (ldSoConf) {
56+
std::string line;
57+
while (std::getline(ldSoConf, line)) {
58+
if (line.empty()) continue;
59+
if (line.find("include ") == 0) {
60+
std::string pattern = line.substr(8);
61+
// Simple glob: /etc/ld.so.conf.d/*.conf
62+
std::string dir = pattern.substr(0, pattern.find_last_of('/'));
63+
std::string ext = pattern.substr(pattern.find_last_of('.'));
64+
DIR* d = opendir(dir.c_str());
65+
if (d) {
66+
struct dirent* ent;
67+
while ((ent = readdir(d)) != nullptr) {
68+
std::string fname = ent->d_name;
69+
if (fname.size() > ext.size() && fname.substr(fname.size()-ext.size()) == ext) {
70+
std::ifstream incFile(dir + "/" + fname);
71+
std::string incLine;
72+
while (std::getline(incFile, incLine)) {
73+
if (!incLine.empty() && incLine[0] != '#')
74+
paths.push_back(incLine);
75+
}
76+
}
77+
}
78+
closedir(d);
79+
}
80+
} else if (line[0] != '#') {
81+
paths.push_back(line);
82+
}
83+
}
84+
}
85+
return paths;
86+
}
87+
88+
// Main function: search for a library file in all known library paths
89+
static bool libraryExistsInSearchPaths(const std::string& filename) {
90+
auto paths = getLibrarySearchPaths();
91+
for (const auto& dir : paths) {
92+
std::string fullPath = dir + "/" + filename;
93+
if (fileExistsReadable(fullPath)) {
94+
return true;
95+
}
96+
}
97+
return false;
98+
}
99+
16100
namespace loader {
17101

18102
static const char *knownDriverNames[] = {
@@ -30,7 +114,9 @@ std::vector<DriverLibraryPath> discoverEnabledDrivers() {
30114
altDrivers = getenv("ZE_ENABLE_ALT_DRIVERS");
31115
if (altDrivers == nullptr) {
32116
for (auto path : knownDriverNames) {
33-
enabledDrivers.emplace_back(path);
117+
if (libraryExistsInSearchPaths(path)) {
118+
enabledDrivers.emplace_back(path);
119+
}
34120
}
35121
} else {
36122
std::stringstream ss(altDrivers);

0 commit comments

Comments
 (0)