7
7
#include <sys/types.h>
8
8
9
9
#include <errno.h>
10
+ #include <libgen.h>
11
+ #undef basename /* Use the GNU version of basename. */
10
12
#include <limits.h>
11
13
#include <stdio.h>
12
14
#include <string.h>
20
22
#include "utils.h"
21
23
#include "xfuncs.h"
22
24
23
- static char * mount_files (struct error * , const struct nvc_container * , const char * , char * [], size_t );
25
+ static char * * mount_files (struct error * , const struct nvc_container * , const char * , char * [], size_t );
24
26
static char * mount_device (struct error * , const struct nvc_container * , const char * );
25
27
static char * mount_ipc (struct error * , const struct nvc_container * , const char * );
26
28
static char * mount_procfs (struct error * , const struct nvc_container * );
@@ -29,32 +31,32 @@ static char *mount_app_profile(struct error *, const struct nvc_container *);
29
31
static int update_app_profile (struct error * , const struct nvc_container * , dev_t );
30
32
static void unmount (const char * );
31
33
static int setup_cgroup (struct error * , const char * , dev_t );
32
- static int symlink_library (struct error * , const char * , const char * , const char * , const char * , uid_t , gid_t );
33
- static int symlink_libraries (struct error * , const struct nvc_container * , const char * , char * [], size_t , const char * );
34
+ static int symlink_library (struct error * , const char * , const char * , const char * , uid_t , gid_t );
35
+ static int symlink_libraries (struct error * , const struct nvc_container * , const char * const [], size_t );
34
36
35
- static char *
37
+ static char * *
36
38
mount_files (struct error * err , const struct nvc_container * cnt , const char * dir , char * paths [], size_t size )
37
39
{
38
40
char path [PATH_MAX ];
39
41
mode_t mode ;
40
- char * ptr , * mnt , * p ;
42
+ char * end , * file ;
43
+ char * * mnt , * * ptr ;
41
44
42
- /* Create the top directory under the rootfs. */
43
45
if (path_resolve (err , path , cnt -> cfg .rootfs , dir ) < 0 )
44
46
return (NULL );
45
47
if (file_create (err , path , NULL , cnt -> uid , cnt -> gid , MODE_DIR (0755 )) < 0 )
46
48
return (NULL );
47
49
48
- ptr = path + strlen (path );
49
-
50
- /* Bind mount the top directory and every files under it with read-only permissions. */
51
- if (xmount (err , path , path , NULL , MS_BIND , NULL ) < 0 )
50
+ end = path + strlen (path );
51
+ mnt = ptr = array_new (err , size + 1 ); /* NULL terminated. */
52
+ if (mnt == NULL )
52
53
goto fail ;
54
+
53
55
for (size_t i = 0 ; i < size ; ++ i ) {
54
- p = basename (paths [i ]);
55
- if (!match_binary_flags (p , cnt -> flags ) && !match_library_flags (p , cnt -> flags ))
56
+ file = basename (paths [i ]);
57
+ if (!match_binary_flags (file , cnt -> flags ) && !match_library_flags (file , cnt -> flags ))
56
58
continue ;
57
- if (path_append (err , path , p ) < 0 )
59
+ if (path_append (err , path , file ) < 0 )
58
60
goto fail ;
59
61
if (file_mode (err , paths [i ], & mode ) < 0 )
60
62
goto fail ;
@@ -66,15 +68,16 @@ mount_files(struct error *err, const struct nvc_container *cnt, const char *dir,
66
68
goto fail ;
67
69
if (xmount (err , NULL , path , NULL , MS_BIND |MS_REMOUNT | MS_RDONLY |MS_NODEV |MS_NOSUID , NULL ) < 0 )
68
70
goto fail ;
69
- * ptr = '\0' ;
71
+ if ((* ptr ++ = xstrdup (err , path )) == NULL )
72
+ goto fail ;
73
+ * end = '\0' ;
70
74
}
71
- if ((mnt = xstrdup (err , path )) == NULL )
72
- goto fail ;
73
75
return (mnt );
74
76
75
77
fail :
76
- * ptr = '\0' ;
77
- unmount (path );
78
+ for (size_t i = 0 ; i < size ; ++ i )
79
+ unmount (mnt [i ]);
80
+ array_free (mnt , size );
78
81
return (NULL );
79
82
}
80
83
@@ -326,41 +329,41 @@ setup_cgroup(struct error *err, const char *cgroup, dev_t id)
326
329
}
327
330
328
331
static int
329
- symlink_library (struct error * err , const char * dir , const char * lib , const char * version , const char * linkname , uid_t uid , gid_t gid )
332
+ symlink_library (struct error * err , const char * src , const char * target , const char * linkname , uid_t uid , gid_t gid )
330
333
{
331
334
char path [PATH_MAX ];
332
- char * target ;
335
+ char * tmp ;
333
336
int rv = -1 ;
334
337
335
- if (path_join (err , path , dir , linkname ) < 0 )
336
- return (-1 );
337
- if (xasprintf (err , & target , "%s.%s" , lib , version ) < 0 )
338
+ if ((tmp = xstrdup (err , src )) == NULL )
338
339
return (-1 );
340
+ if (path_join (err , path , dirname (tmp ), linkname ) < 0 )
341
+ goto fail ;
339
342
340
343
log_infof ("creating symlink %s -> %s" , path , target );
341
344
if (file_create (err , path , target , uid , gid , MODE_LNK (0777 )) < 0 )
342
345
goto fail ;
343
346
rv = 0 ;
344
347
345
348
fail :
346
- free (target );
349
+ free (tmp );
347
350
return (rv );
348
351
}
349
352
350
353
static int
351
- symlink_libraries (struct error * err , const struct nvc_container * cnt , const char * dir , char * paths [], size_t size , const char * version )
354
+ symlink_libraries (struct error * err , const struct nvc_container * cnt , const char * const paths [], size_t size )
352
355
{
353
- char * p ;
356
+ char * lib ;
354
357
355
358
for (size_t i = 0 ; i < size ; ++ i ) {
356
- p = basename (paths [i ]);
357
- if (( cnt -> flags & OPT_COMPUTE_LIBS ) && !strpcmp (p , "libcuda.so" )) {
359
+ lib = basename (paths [i ]);
360
+ if (!strpcmp (lib , "libcuda.so" )) {
358
361
/* XXX Many applications wrongly assume that libcuda.so exists (e.g. with dlopen). */
359
- if (symlink_library (err , dir , "libcuda.so" , version , "libcuda.so" , cnt -> uid , cnt -> gid ) < 0 )
362
+ if (symlink_library (err , paths [ i ], lib , "libcuda.so" , cnt -> uid , cnt -> gid ) < 0 )
360
363
return (-1 );
361
- } else if (( cnt -> flags & OPT_GRAPHICS_LIBS ) && !strpcmp (p , "libGLX_nvidia.so" )) {
364
+ } else if (!strpcmp (lib , "libGLX_nvidia.so" )) {
362
365
/* XXX GLVND requires this symlink for indirect GLX support. */
363
- if (symlink_library (err , dir , "libGLX_nvidia.so" , version , "libGLX_indirect.so.0" , cnt -> uid , cnt -> gid ) < 0 )
366
+ if (symlink_library (err , paths [ i ], lib , "libGLX_indirect.so.0" , cnt -> uid , cnt -> gid ) < 0 )
364
367
return (-1 );
365
368
}
366
369
}
@@ -370,7 +373,7 @@ symlink_libraries(struct error *err, const struct nvc_container *cnt, const char
370
373
int
371
374
nvc_driver_mount (struct nvc_context * ctx , const struct nvc_container * cnt , const struct nvc_driver_info * info )
372
375
{
373
- char * * mnt , * * ptr ;
376
+ const char * * mnt , * * ptr , * * tmp ;
374
377
size_t nmnt ;
375
378
int rv = -1 ;
376
379
@@ -382,8 +385,8 @@ nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
382
385
if (nsenter (& ctx -> err , cnt -> mnt_ns , CLONE_NEWNS ) < 0 )
383
386
return (-1 );
384
387
385
- nmnt = 5 + info -> nipcs + info -> ndevs ;
386
- mnt = ptr = array_new (& ctx -> err , nmnt );
388
+ nmnt = 2 + info -> nbins + info -> nlibs + info -> nlibs32 + info -> nipcs + info -> ndevs ;
389
+ mnt = ptr = ( const char * * ) array_new (& ctx -> err , nmnt );
387
390
if (mnt == NULL )
388
391
goto fail ;
389
392
@@ -395,25 +398,27 @@ nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
395
398
if ((* ptr ++ = mount_app_profile (& ctx -> err , cnt )) == NULL )
396
399
goto fail ;
397
400
}
398
- /* Binary and library file mounts */
401
+ /* Binary and library mounts */
399
402
if (info -> bins != NULL && info -> nbins > 0 ) {
400
- if ((* ptr ++ = mount_files (& ctx -> err , cnt , cnt -> cfg .bins_dir , info -> bins , info -> nbins )) == NULL )
403
+ if ((tmp = ( const char * * ) mount_files (& ctx -> err , cnt , cnt -> cfg .bins_dir , info -> bins , info -> nbins )) == NULL )
401
404
goto fail ;
405
+ ptr = array_append (ptr , tmp , array_size (tmp ));
406
+ free (tmp );
402
407
}
403
408
if (info -> libs != NULL && info -> nlibs > 0 ) {
404
- if ((* ptr = mount_files (& ctx -> err , cnt , cnt -> cfg .libs_dir , info -> libs , info -> nlibs )) == NULL )
405
- goto fail ;
406
- if (symlink_libraries (& ctx -> err , cnt , * ptr , info -> libs , info -> nlibs , info -> nvrm_version ) < 0 )
409
+ if ((tmp = (const char * * )mount_files (& ctx -> err , cnt , cnt -> cfg .libs_dir , info -> libs , info -> nlibs )) == NULL )
407
410
goto fail ;
408
- ++ ptr ;
411
+ ptr = array_append (ptr , tmp , array_size (tmp ));
412
+ free (tmp );
409
413
}
410
414
if ((cnt -> flags & OPT_COMPAT32 ) && info -> libs32 != NULL && info -> nlibs32 > 0 ) {
411
- if ((* ptr = mount_files (& ctx -> err , cnt , cnt -> cfg .libs32_dir , info -> libs32 , info -> nlibs32 )) == NULL )
415
+ if ((tmp = ( const char * * ) mount_files (& ctx -> err , cnt , cnt -> cfg .libs32_dir , info -> libs32 , info -> nlibs32 )) == NULL )
412
416
goto fail ;
413
- if (symlink_libraries (& ctx -> err , cnt , * ptr , info -> libs32 , info -> nlibs32 , info -> nvrm_version ) < 0 )
414
- goto fail ;
415
- ++ ptr ;
417
+ ptr = array_append (ptr , tmp , array_size (tmp ));
418
+ free (tmp );
416
419
}
420
+ if (symlink_libraries (& ctx -> err , cnt , mnt , (size_t )(ptr - mnt )) < 0 )
421
+ goto fail ;
417
422
/* IPC mounts */
418
423
for (size_t i = 0 ; i < info -> nipcs ; ++ i ) {
419
424
/* XXX Only utility libraries require persistenced IPC, everything else is compute only. */
@@ -450,7 +455,7 @@ nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
450
455
rv = nsenterat (& ctx -> err , ctx -> mnt_ns , CLONE_NEWNS );
451
456
}
452
457
453
- array_free (mnt , nmnt );
458
+ array_free (( char * * ) mnt , nmnt );
454
459
return (rv );
455
460
}
456
461
0 commit comments