From 5c1a7e2c387875c0659428db0fd9bb407edf04a8 Mon Sep 17 00:00:00 2001 From: Kevin Klues Date: Wed, 15 Feb 2023 14:54:39 +0000 Subject: [PATCH] Add globbing for mounting multiple GSP firmware files Newer drivers have split the GSP firmware into multiple files so a simple match against gsp.bin in the firmware directory is no longer possible. This patch adds globbing capabilitis to match any GSP firmware files of the form gsp*.bin and mount them all into the container. --- src/nvc_info.c | 73 ++++++++++++++++++++++++++++++++-------------- src/nvc_internal.h | 4 +-- 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/src/nvc_info.c b/src/nvc_info.c index f0c2e5a8..9e27c3c8 100644 --- a/src/nvc_info.c +++ b/src/nvc_info.c @@ -430,45 +430,74 @@ lookup_binaries(struct error *err, struct dxcore_context* dxcore, struct nvc_dri } static int -lookup_firmwares(struct error *err, struct dxcore_context *dxcore, struct nvc_driver_info *info, const char *root, int32_t flags) { +lookup_firmwares(struct error *err, struct dxcore_context *dxcore, struct nvc_driver_info *info, const char *root, int32_t flags) +{ (void)flags; - char **ptr; - int rc = -1; + glob_t gl; + char glob_path[PATH_MAX]; char *firmware_path = NULL; - char *resolved_path = NULL; + int rv = -1; if (dxcore->initialized) { log_info("skipping path lookup for dxcore"); - return 0; + goto success; } - // If the NVIDIA driver firmware path exists, include this in the mounted folders. - if (xasprintf(err, &firmware_path, NV_FIRMWARE_DRIVER_PATH, info->nvrm_version) < 0) { + // Construct the fully resolved NV_FIRMWARE_PATH_GLOB. + if (xasprintf(err, &firmware_path, NV_FIRMWARE_PATH, info->nvrm_version) < 0) { log_errf("error constructing firmware path for %s", info->nvrm_version); - return (-1); + goto fail; + } + if (path_resolve_full(err, glob_path, root, firmware_path) < 0) { + log_errf("error resolving firmware path %s", firmware_path); + goto fail; + } + if (path_append(err, glob_path, NV_FIRMWARE_GLOB) < 0) { + log_errf("error appending glob to firmware path %s", firmware_path); + goto fail; } - if (find_path(err, "firmware", root, firmware_path, &resolved_path) < 0) { - log_errf("error finding firmware path %s", firmware_path); - goto cleanup; + + // Walk each path matched in the fully resolved glob_path and + // include the non-resolved path in our list of mounted files. + if (xglob(err, glob_path, GLOB_ERR, NULL, &gl) < 0) { + log_errf("error processing firmware path glob of %s", glob_path); + goto fail; } - if (resolved_path == NULL) { - rc = 0; - goto cleanup; + + if (gl.gl_pathc == 0) { + log_warnf("missing firmware path %s", glob_path); + goto success; } - info->nfirmwares = 1; - info->firmwares = ptr = array_new(err, info->nfirmwares); + info->nfirmwares = gl.gl_pathc; + info->firmwares = array_new(err, gl.gl_pathc); if (info->firmwares == NULL) { - log_err("error creating path array"); - goto cleanup; + log_err("error creating firmware paths array"); + goto fail; } - info->firmwares[0] = firmware_path; - return (0); -cleanup: + for (size_t i = 0; i < gl.gl_pathc; ++i) { + strcpy(glob_path, firmware_path); + if (path_append(err, glob_path, basename(gl.gl_pathv[i])) < 0) { + log_err("error appending firmware filename to unresolved firmware path"); + goto fail; + } + log_infof("listing firmware path %s", glob_path); + if ((info->firmwares[i] = xstrdup(err, glob_path)) == NULL) { + log_err("error copying firmware path into array"); + goto fail; + } + } + + array_pack(info->firmwares, &info->nfirmwares); + +success: + rv = 0; +fail: free(firmware_path); - return (rc); + globfree(&gl); + return (rv); } static int diff --git a/src/nvc_internal.h b/src/nvc_internal.h index d947ad43..cd1d785b 100644 --- a/src/nvc_internal.h +++ b/src/nvc_internal.h @@ -58,8 +58,8 @@ #define CUDA_RUNTIME_DIR "/usr/local/cuda" -#define NV_FIRMWARE_PATH "/lib/firmware/nvidia" -#define NV_FIRMWARE_DRIVER_PATH NV_FIRMWARE_PATH "/%s/gsp.bin" +#define NV_FIRMWARE_PATH "/lib/firmware/nvidia/%s" +#define NV_FIRMWARE_GLOB "gsp*.bin" #define MSFT_DXG_DEVICE_PATH _PATH_DEV "dxg"