2
2
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
3
3
*/
4
4
5
+ #include <sys/sysmacros.h>
5
6
#include <sys/mount.h>
6
7
#include <sys/types.h>
7
8
@@ -24,6 +25,8 @@ static char *mount_device(struct error *, const struct nvc_container *, const ch
24
25
static char * mount_ipc (struct error * , const struct nvc_container * , const char * );
25
26
static char * mount_procfs (struct error * , const struct nvc_container * );
26
27
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 );
27
30
static void unmount (const char * );
28
31
static int setup_cgroup (struct error * , const char * , dev_t );
29
32
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)
128
131
return (NULL );
129
132
}
130
133
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
+
131
204
static char *
132
205
mount_procfs (struct error * err , const struct nvc_container * cnt )
133
206
{
@@ -294,6 +367,7 @@ symlink_libraries(struct error *err, const struct nvc_container *cnt, const char
294
367
int
295
368
nvc_driver_mount (struct nvc_context * ctx , const struct nvc_container * cnt , const struct nvc_driver_info * info )
296
369
{
370
+ char * approf_mnt = NULL ;
297
371
char * procfs_mnt = NULL ;
298
372
char * * files_mnt = NULL ;
299
373
char * * ipcs_mnt = NULL ;
@@ -316,6 +390,10 @@ nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
316
390
if ((procfs_mnt = mount_procfs (& ctx -> err , cnt )) == NULL )
317
391
goto fail ;
318
392
393
+ /* Application profile mount */
394
+ if ((approf_mnt = mount_app_profile (& ctx -> err , cnt )) == NULL )
395
+ goto fail ;
396
+
319
397
/* File mounts */
320
398
nfiles_mnt = 3 ;
321
399
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
371
449
fail :
372
450
if (rv < 0 ) {
373
451
unmount (procfs_mnt );
452
+ unmount (approf_mnt );
374
453
for (size_t i = 0 ; files_mnt != NULL && i < nfiles_mnt ; ++ i )
375
454
unmount (files_mnt [i ]);
376
455
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
383
462
}
384
463
385
464
free (procfs_mnt );
465
+ free (approf_mnt );
386
466
array_free (files_mnt , nfiles_mnt );
387
467
array_free (ipcs_mnt , nipcs_mnt );
388
468
array_free (devs_mnt , ndevs_mnt );
@@ -417,6 +497,8 @@ nvc_device_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
417
497
}
418
498
if ((proc_mnt = mount_procfs_gpu (& ctx -> err , cnt , dev -> busid )) == NULL )
419
499
goto fail ;
500
+ if (update_app_profile (& ctx -> err , cnt , dev -> node .id ) < 0 )
501
+ goto fail ;
420
502
if (!(cnt -> flags & OPT_NO_CGROUPS )) {
421
503
if (setup_cgroup (& ctx -> err , cnt -> dev_cg , dev -> node .id ) < 0 )
422
504
goto fail ;
0 commit comments