Skip to content

Commit ea2f780

Browse files
committed
Add support for EGL device isolation
1 parent e94a4d3 commit ea2f780

File tree

4 files changed

+85
-1
lines changed

4 files changed

+85
-1
lines changed

src/nvc_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#define NV_MPS_PIPE_DIR _PATH_TMP "nvidia-mps"
3333
#define NV_PROC_DRIVER "/proc/driver/nvidia"
3434
#define NV_UVM_PROC_DRIVER "/proc/driver/nvidia-uvm"
35+
#define NV_APP_PROFILE_DIR "/etc/nvidia/nvidia-application-profiles-rc.d"
3536

3637
struct nvc_context {
3738
bool initialized;

src/nvc_mount.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
33
*/
44

5+
#include <sys/sysmacros.h>
56
#include <sys/mount.h>
67
#include <sys/types.h>
78

@@ -24,6 +25,8 @@ static char *mount_device(struct error *, const struct nvc_container *, const ch
2425
static char *mount_ipc(struct error *, const struct nvc_container *, const char *);
2526
static char *mount_procfs(struct error *, const struct nvc_container *);
2627
static char *mount_procfs_gpu(struct error *, const struct nvc_container *, const char *);
28+
static char *mount_app_profile(struct error *, const struct nvc_container *);
29+
static int update_app_profile(struct error *, const struct nvc_container *, dev_t);
2730
static void unmount(const char *);
2831
static int setup_cgroup(struct error *, const char *, dev_t);
2932
static int symlink_library(struct error *, const char *, const char *, const char *, const char *, uid_t, gid_t);
@@ -128,6 +131,76 @@ mount_ipc(struct error *err, const struct nvc_container *cnt, const char *ipc)
128131
return (NULL);
129132
}
130133

134+
static char *
135+
mount_app_profile(struct error *err, const struct nvc_container *cnt)
136+
{
137+
char path[PATH_MAX];
138+
char *mnt;
139+
140+
if (path_resolve(err, path, cnt->cfg.rootfs, NV_APP_PROFILE_DIR) < 0)
141+
return (NULL);
142+
if (file_create(err, path, NULL, cnt->uid, cnt->gid, MODE_DIR(0555)) < 0)
143+
goto fail;
144+
145+
log_infof("mounting tmpfs at %s", path);
146+
if (xmount(err, "tmpfs", path, "tmpfs", 0, "mode=0555") < 0)
147+
goto fail;
148+
/* XXX Some kernels require MS_BIND in order to remount within a userns */
149+
if (xmount(err, NULL, path, NULL, MS_BIND|MS_REMOUNT | MS_NODEV|MS_NOSUID|MS_NOEXEC, NULL) < 0)
150+
goto fail;
151+
if ((mnt = xstrdup(err, path)) == NULL)
152+
goto fail;
153+
return (mnt);
154+
155+
fail:
156+
unmount(path);
157+
return (NULL);
158+
}
159+
160+
static int
161+
update_app_profile(struct error *err, const struct nvc_container *cnt, dev_t id)
162+
{
163+
char path[PATH_MAX];
164+
char *buf = NULL;
165+
char *ptr;
166+
uintmax_t n;
167+
uint64_t dev;
168+
int rv = -1;
169+
170+
#define profile quote_str({\
171+
"profiles": [{"name": "_container_", "settings": ["EGLVisibleDGPUDevices", 0x%lx]}],\
172+
"rules": [{"pattern": [], "profile": "_container_"}]\
173+
})
174+
175+
dev = 1ull << minor(id);
176+
if (path_resolve(err, path, cnt->cfg.rootfs, NV_APP_PROFILE_DIR "/10-container.conf") < 0)
177+
return (-1);
178+
if (file_read_text(err, path, &buf) < 0) {
179+
if (err->code != ENOENT)
180+
goto fail;
181+
if (xasprintf(err, &buf, profile, dev) < 0)
182+
goto fail;
183+
} else {
184+
if ((ptr = strstr(buf, "0x")) == NULL ||
185+
(n = strtoumax(ptr, NULL, 16)) == UINTMAX_MAX) {
186+
error_setx(err, "invalid application profile: %s", path);
187+
goto fail;
188+
}
189+
free(buf), buf = NULL;
190+
if (xasprintf(err, &buf, profile, (uint64_t)n|dev) < 0)
191+
goto fail;
192+
}
193+
if (file_create(err, path, buf, cnt->uid, cnt->gid, MODE_REG(0555)) < 0)
194+
goto fail;
195+
rv = 0;
196+
197+
#undef profile
198+
199+
fail:
200+
free(buf);
201+
return (rv);
202+
}
203+
131204
static char *
132205
mount_procfs(struct error *err, const struct nvc_container *cnt)
133206
{
@@ -294,6 +367,7 @@ symlink_libraries(struct error *err, const struct nvc_container *cnt, const char
294367
int
295368
nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const struct nvc_driver_info *info)
296369
{
370+
char *approf_mnt = NULL;
297371
char *procfs_mnt = NULL;
298372
char **files_mnt = NULL;
299373
char **ipcs_mnt = NULL;
@@ -316,6 +390,10 @@ nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
316390
if ((procfs_mnt = mount_procfs(&ctx->err, cnt)) == NULL)
317391
goto fail;
318392

393+
/* Application profile mount */
394+
if ((approf_mnt = mount_app_profile(&ctx->err, cnt)) == NULL)
395+
goto fail;
396+
319397
/* File mounts */
320398
nfiles_mnt = 3;
321399
files_mnt = mnt = array_new(&ctx->err, nfiles_mnt);
@@ -371,6 +449,7 @@ nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
371449
fail:
372450
if (rv < 0) {
373451
unmount(procfs_mnt);
452+
unmount(approf_mnt);
374453
for (size_t i = 0; files_mnt != NULL && i < nfiles_mnt; ++i)
375454
unmount(files_mnt[i]);
376455
for (size_t i = 0; ipcs_mnt != NULL && i < nipcs_mnt; ++i)
@@ -383,6 +462,7 @@ nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
383462
}
384463

385464
free(procfs_mnt);
465+
free(approf_mnt);
386466
array_free(files_mnt, nfiles_mnt);
387467
array_free(ipcs_mnt, nipcs_mnt);
388468
array_free(devs_mnt, ndevs_mnt);
@@ -417,6 +497,8 @@ nvc_device_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
417497
}
418498
if ((proc_mnt = mount_procfs_gpu(&ctx->err, cnt, dev->busid)) == NULL)
419499
goto fail;
500+
if (update_app_profile(&ctx->err, cnt, dev->node.id) < 0)
501+
goto fail;
420502
if (!(cnt->flags & OPT_NO_CGROUPS)) {
421503
if (setup_cgroup(&ctx->err, cnt->dev_cg, dev->node.id) < 0)
422504
goto fail;

src/utils.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ file_create(struct error *err, const char *path, const char *data, uid_t uid, gi
470470
} else {
471471
if (data != NULL) {
472472
size = strlen(data);
473-
flags |= O_WRONLY;
473+
flags |= O_WRONLY|O_TRUNC;
474474
}
475475
if ((fd = open(path, flags, perm)) < 0)
476476
goto fail;

src/utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#define CAP_AMBIENT (cap_flag_t)-1
1919

20+
#define quote_str(...) #__VA_ARGS__
2021
#define nitems(x) (sizeof(x) / sizeof(*x))
2122
#define maybe_unused __attribute__((unused))
2223
#define assert_func(fn) do { \

0 commit comments

Comments
 (0)