Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/deb/libnvidia-container@MAJOR@.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ libnvidia-container.so.1 libnvidia-container1 #MINVER#
nvc_device_mig_caps_mount@NVC_1.0 @VERSION_TAG@
nvc_driver_info_free@NVC_1.0 @VERSION_TAG@
nvc_driver_info_new@NVC_1.0 @VERSION_TAG@
nvc_symlink_libraries@NVC_1.0 @VERSION_TAG@
nvc_driver_mount@NVC_1.0 @VERSION_TAG@
nvc_error@NVC_1.0 @VERSION_TAG@
nvc_init@NVC_1.0 @VERSION_TAG@
Expand Down
5 changes: 4 additions & 1 deletion src/cli/configure.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,10 @@ configure_command(const struct context *ctx)
warnx("ldcache error: %s", libnvc.error(nvc));
goto fail;
}

if (libnvc.symlink_libraries(nvc, cnt, drv) < 0) {
warnx("symlink libraries error: %s", libnvc.error(nvc));
goto fail;
}
if (perm_set_capabilities(&err, CAP_EFFECTIVE, ecaps[NVC_SHUTDOWN], ecaps_size(NVC_SHUTDOWN)) < 0) {
warnx("permission error: %s", err.msg);
goto fail;
Expand Down
12 changes: 11 additions & 1 deletion src/cli/libnvc.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ static int libnvc_v0_wrapper_device_mount(struct nvc_context *, const struct nvc
static void libnvc_v0_wrapper_driver_info_free(struct nvc_driver_info *);
static struct nvc_driver_info *libnvc_v0_wrapper_driver_info_new(struct nvc_context *, const char *);
static int libnvc_v0_wrapper_driver_mount(struct nvc_context *, const struct nvc_container *, const struct nvc_driver_info *);

static int libnvc_v0_wrapper_symlink_libraries(struct nvc_context *, const struct nvc_container *, const struct nvc_driver_info *);
int
load_libnvc(void)
{
Expand Down Expand Up @@ -93,6 +93,7 @@ load_libnvc_v0(void)
funcs_entry(device_mount),
funcs_entry(driver_info_free),
funcs_entry(driver_info_new),
funcs_entry(symlink_libraries),
funcs_entry(driver_mount),
funcs_entry(error),
funcs_entry(init),
Expand Down Expand Up @@ -125,6 +126,7 @@ load_libnvc_v0(void)
wrap_libnvc_func(device_mount);
wrap_libnvc_func(driver_info_free);
wrap_libnvc_func(driver_info_new);
wrap_libnvc_func(symlink_libraries);
wrap_libnvc_func(driver_mount);

return (0);
Expand All @@ -149,6 +151,7 @@ load_libnvc_v1(void)
load_libnvc_func(device_mount);
load_libnvc_func(driver_info_free);
load_libnvc_func(driver_info_new);
load_libnvc_func(symlink_libraries);
load_libnvc_func(driver_mount);
load_libnvc_func(error);
load_libnvc_func(init);
Expand Down Expand Up @@ -309,3 +312,10 @@ libnvc_v0_wrapper_driver_mount(struct nvc_context *ctx, const struct nvc_contain
struct libnvc_v0_wrapper_driver_info *info = (void*)info_;
return libnvc_v0_wrapped.driver_mount(ctx, cnt, info->v0);
}

static int
libnvc_v0_wrapper_symlink_libraries(struct nvc_context *ctx, const struct nvc_container *cnt, const struct nvc_driver_info *info_)
{
struct libnvc_v0_wrapper_driver_info *info = (void*)info_;
return libnvc_v0_wrapped.symlink_libraries(ctx, cnt, info->v0);
}
1 change: 1 addition & 0 deletions src/cli/libnvc.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct libnvc {
libnvc_entry(device_mount);
libnvc_entry(driver_info_free);
libnvc_entry(driver_info_new);
libnvc_entry(symlink_libraries);
libnvc_entry(driver_mount);
libnvc_entry(error);
libnvc_entry(init);
Expand Down
1 change: 1 addition & 0 deletions src/libnvidia-container.lds
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ VERSION {
nvc_driver_info_free;
nvc_device_info_new;
nvc_device_info_free;
nvc_symlink_libraries;
nvc_driver_mount;
nvc_device_mount;
nvc_nvcaps_style;
Expand Down
2 changes: 2 additions & 0 deletions src/nvc.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ int nvc_nvcaps_style(void);

int nvc_nvcaps_device_from_proc_path(struct nvc_context *, const char *, struct nvc_device_node *);

int nvc_symlink_libraries(struct nvc_context *, const struct nvc_container *, const struct nvc_driver_info *);

int nvc_driver_mount(struct nvc_context *, const struct nvc_container *, const struct nvc_driver_info *);

int nvc_device_mount(struct nvc_context *, const struct nvc_container *, const struct nvc_device *);
Expand Down
85 changes: 80 additions & 5 deletions src/nvc_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static char *mount_app_profile(struct error *, const struct nvc_container *);
static int update_app_profile(struct error *, const struct nvc_container *, dev_t);
static void unmount(const char *);
static int symlink_library(struct error *, const char *, const char *, const char *, uid_t, gid_t);
static int symlink_libraries(struct error *, const struct nvc_container *, const char * const [], size_t);
static int symlink_libraries(struct error *, const struct nvc_container *, const struct nvc_driver_info *info, const char * const [], size_t);
static void filter_libraries(const struct nvc_driver_info *, char * [], size_t *);
static int device_mount_dxcore(struct nvc_context *, const struct nvc_container *);
static int device_mount_native(struct nvc_context *, const struct nvc_container *, const struct nvc_device *);
Expand Down Expand Up @@ -525,6 +525,7 @@ symlink_library(struct error *err, const char *src, const char *target, const ch
goto fail;

log_infof("creating symlink %s -> %s", path, target);
symlink_remove(err, path);
if (file_create(err, path, target, uid, gid, MODE_LNK(0777)) < 0)
goto fail;
rv = 0;
Expand All @@ -535,10 +536,10 @@ symlink_library(struct error *err, const char *src, const char *target, const ch
}

static int
symlink_libraries(struct error *err, const struct nvc_container *cnt, const char * const paths[], size_t size)
symlink_libraries(struct error *err, const struct nvc_container *cnt, const struct nvc_driver_info *info, const char * const paths[], size_t size)
{
char *lib;

char *src;
for (size_t i = 0; i < size; ++i) {
lib = basename(paths[i]);
if (str_has_prefix(lib, "libcuda.so")) {
Expand All @@ -553,7 +554,16 @@ symlink_libraries(struct error *err, const struct nvc_container *cnt, const char
/* XXX Fix missing symlink for libnvidia-opticalflow.so. */
if (symlink_library(err, paths[i], "libnvidia-opticalflow.so.1", "libnvidia-opticalflow.so", cnt->uid, cnt->gid) < 0)
return (-1);
}
} else if (match_library_flags(lib, cnt->flags) && str_has_suffix(lib, info->nvrm_version)) {
src = xstrdup(err, lib);
src[strlen(src) - strlen(info->nvrm_version) - 1] = '\0';
strcat(src, ".1");
if (symlink_library(err, paths[i], lib, src, cnt->uid, cnt->gid) < 0) {
free(src);
return (-1);
}
free(src);
}
}
return (0);
}
Expand Down Expand Up @@ -708,6 +718,71 @@ setup_mig_minor_cgroups(struct error *err, const struct nvc_container *cnt, int
return (rv);
}

int
nvc_symlink_libraries(struct nvc_context *ctx, const struct nvc_container *cnt, const struct nvc_driver_info *info)
{
const char **libs, **ptr;
char dst[PATH_MAX];
char *dst_end;
char *file;
int rv = -1;
size_t nlibs;
if (validate_context(ctx) < 0)
return (-1);
if (validate_args(ctx, cnt != NULL && info != NULL) < 0)
return (-1);

nlibs = 2 + info->nlibs + info->nlibs32;

libs = ptr = (const char **)array_new(&ctx->err, nlibs);

if (info->libs != NULL && info->nlibs > 0) {
if (path_resolve_full(&ctx->err, dst, cnt->cfg.rootfs, cnt->cfg.libs_dir) < 0) {
rv = -1;
goto fail;
}
dst_end = dst + strlen(dst);
for (size_t i = 0; i < info->nlibs; i++) {
file = basename(info->libs[i]);
if (!match_library_flags(file, cnt->flags))
continue;
if (path_append(&ctx->err, dst, file) < 0) {
rv = -1;
goto fail;
}

if ((*ptr ++ = xstrdup(&ctx->err, dst))== NULL)
goto fail;
*dst_end = '\0';
}
}
if ((cnt->flags & OPT_COMPAT32) && info->libs32 != NULL && info->nlibs32 > 0) {
if (path_resolve_full(&ctx->err, dst, cnt->cfg.rootfs, cnt->cfg.libs32_dir) < 0) {
rv = -1;
goto fail;
}
dst_end = dst + strlen(dst);
for (size_t i = 0; i < info->nlibs32; i++) {
file = basename(info->libs32[i]);
if (!match_library_flags(file, cnt->flags))
continue;
if (path_append(&ctx->err, dst, file) < 0) {
rv = -1;
goto fail;
}

if ((*ptr ++ = xstrdup(&ctx->err, dst))== NULL)
goto fail;
*dst_end = '\0';
}
}
symlink_libraries(&ctx->err, cnt, info, libs, (size_t)(ptr - libs));
rv = 0;
fail:
array_free((char **)libs, nlibs);
return (rv);
}

int
nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const struct nvc_driver_info *info)
{
Expand Down Expand Up @@ -761,7 +836,7 @@ nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
ptr = array_append(ptr, tmp, array_size(tmp));
free(tmp);
}
if (symlink_libraries(&ctx->err, cnt, mnt, (size_t)(ptr - mnt)) < 0)
if (symlink_libraries(&ctx->err, cnt, info, mnt, (size_t)(ptr - mnt)) < 0)
goto fail;

/* Container library mounts */
Expand Down
14 changes: 14 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,20 @@ do_file_remove(const char *path, const struct stat *s, int flag, maybe_unused st
return (0);
}

int
symlink_remove(struct error *err, const char *path)
{
struct stat path_stat;
if (lstat(path, &path_stat) != 0) {
error_set(err, "file removal failed: %s", path);
return (-1);
}
if (S_ISLNK(path_stat.st_mode))
return (unlink(path));
error_set(err, "%s is not a symlink", path);
return (-1);
}

int
file_remove(struct error *err, const char *path)
{
Expand Down
1 change: 1 addition & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const char **array_append(const char **, const char * const [], size_t);
void *file_map(struct error *, const char *, size_t *);
int file_unmap(struct error *, const char *, void *, size_t);
int file_create(struct error *, const char *, const char *, uid_t, gid_t, mode_t);
int symlink_remove(struct error *, const char *);
int file_remove(struct error *, const char *);
int file_exists(struct error *, const char *);
int file_exists_at(struct error *, const char *, const char *);
Expand Down