Skip to content

Commit a29412b

Browse files
committed
feat: auto-detect NVIDIA GPU via CDI
When no CDI devices are explicitly specified, automatically detect nvidia.com/gpu=all and use it for GPU support, skipping the legacy detectDrivers() call. Signed-off-by: reddevillg <reddevillg@gmail.com>
1 parent c7f3a69 commit a29412b

3 files changed

Lines changed: 55 additions & 9 deletions

File tree

libs/cdi/src/linglong/cdi/cdi.cpp

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,17 @@ utils::error::Result<types::ContainerEdits> getCDIDeviceEdits(const types::Cdi &
167167

168168
} // namespace
169169

170-
utils::error::Result<std::vector<api::types::v1::CdiDeviceEntry>>
171-
getCDIDevices(const std::vector<std::string> &specDirs, const std::vector<std::string> &devices)
170+
utils::error::Result<std::vector<api::types::v1::CdiDeviceEntry>> getCDIDevices(
171+
const std::vector<std::string> &specDirs, const std::optional<std::vector<std::string>> &devices)
172172
{
173-
LINGLONG_TRACE(fmt::format("get CDI devices {} from {}",
174-
fmt::join(devices, ", "),
175-
fmt::join(specDirs, ", ")));
173+
std::string devicesStr;
174+
if (devices) {
175+
devicesStr = fmt::format("{}", fmt::join(*devices, ", "));
176+
} else {
177+
devicesStr = "(all)";
178+
}
179+
LINGLONG_TRACE(
180+
fmt::format("get CDI devices {} from {}", devicesStr, fmt::join(specDirs, ", ")));
176181

177182
struct ParsedSpec
178183
{
@@ -212,7 +217,25 @@ getCDIDevices(const std::vector<std::string> &specDirs, const std::vector<std::s
212217
}
213218

214219
std::vector<api::types::v1::CdiDeviceEntry> result;
215-
for (const auto &deviceStr : devices) {
220+
221+
if (!devices) {
222+
for (const auto &spec : specs) {
223+
for (const auto &dev : spec.spec.devices) {
224+
result.emplace_back(api::types::v1::CdiDeviceEntry{
225+
.kind = spec.spec.kind,
226+
.name = dev.name,
227+
.spec =
228+
api::types::v1::CdiSpec{
229+
.checksum = spec.checksum,
230+
.path = spec.path.string(),
231+
},
232+
});
233+
}
234+
}
235+
return result;
236+
}
237+
238+
for (const auto &deviceStr : *devices) {
216239
auto device = common::strings::split(deviceStr, '=');
217240
if (device.size() != 2) {
218241
return LINGLONG_ERR(fmt::format("invalid device format: {}", deviceStr));

libs/cdi/src/linglong/cdi/cdi.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@
1111
#include "linglong/utils/error/error.h"
1212

1313
#include <map>
14+
#include <optional>
1415
#include <string>
1516
#include <vector>
1617

1718
namespace linglong::cdi {
1819

19-
utils::error::Result<std::vector<api::types::v1::CdiDeviceEntry>>
20-
getCDIDevices(const std::vector<std::string> &specDirs, const std::vector<std::string> &devices);
20+
utils::error::Result<std::vector<api::types::v1::CdiDeviceEntry>> getCDIDevices(
21+
const std::vector<std::string> &specDirs, const std::optional<std::vector<std::string>> &devices);
2122

2223
utils::error::Result<types::ContainerEdits>
2324
getCDIDeviceEdits(const api::types::v1::CdiDeviceEntry &device);

libs/linglong/src/linglong/cli/cli.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,27 @@ int Cli::run(const RunOptions &options)
563563
{
564564
LINGLONG_TRACE("command run");
565565

566-
detectDrivers();
566+
bool nvidiaCdiFound = false;
567+
std::optional<std::vector<api::types::v1::CdiDeviceEntry>> autoDetectedCdiDevices;
568+
569+
if (options.cdiDevices.empty()) {
570+
LogD("detect cdi devices");
571+
auto allCdiDevices = cdi::getCDIDevices(options.cdiSpecDir, std::nullopt);
572+
if (allCdiDevices) {
573+
for (const auto &device : *allCdiDevices) {
574+
LogD("{}={} detected", device.kind, device.name);
575+
if (device.kind == "nvidia.com/gpu" && device.name == "all") {
576+
nvidiaCdiFound = true;
577+
autoDetectedCdiDevices = std::vector<api::types::v1::CdiDeviceEntry>{ device };
578+
break;
579+
}
580+
}
581+
}
582+
}
583+
584+
if (!nvidiaCdiFound) {
585+
detectDrivers();
586+
}
567587

568588
auto userContainerDir = std::filesystem::path{ "/run/linglong" } / std::to_string(getuid());
569589
if (auto ret = utils::ensureDirectory(userContainerDir); !ret) {
@@ -630,6 +650,8 @@ int Cli::run(const RunOptions &options)
630650
return -1;
631651
}
632652
opts.cdiDevices = std::move(*cdiDevices);
653+
} else if (autoDetectedCdiDevices) {
654+
opts.cdiDevices = std::move(*autoDetectedCdiDevices);
633655
}
634656

635657
// 调整日志输出,打印扩展列表(用逗号拼接)

0 commit comments

Comments
 (0)