Skip to content
Snippets Groups Projects

pressure-vessel: Remap preloadable modules better

Merged Simon McVittie requested to merge wip/t29490 into master
1 file
+ 21
0
Compare changes
  • Side-by-side
  • Inline
  • 1afa455f
    When pressure-vessel maps LD_PRELOAD options into a container, it's not
    completely obvious what to do with a plain basename. If it's
    LD_PRELOAD=libMangoHud.so, then we'll want to import that library into
    the container and load it. However, if it's something like
    LD_PRELOAD=libcurl.so.4, then arbitrarily deciding that we will load
    the one from the host system seems like it defeats the object of the
    predictable runtime environment.
    
    We can avoid this by assuming that if a particular SONAME exists in the
    container, then we should probably interpret LD_PRELOADing it as meaning
    use the container's version, even if the version from the provider
    (host system) appears newer. The if-not-in-container flag makes this
    implementable.
    
    If the library has dependencies, they are compared between container
    and provider as usual.
    
    Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>
@@ -285,6 +285,9 @@ static void usage (int code)
@@ -285,6 +285,9 @@ static void usage (int code)
fprintf( fh, "even-if-older:PATTERN\n"
fprintf( fh, "even-if-older:PATTERN\n"
"\tCapture PATTERN, even if the version in CONTAINER\n"
"\tCapture PATTERN, even if the version in CONTAINER\n"
"\tappears newer\n" );
"\tappears newer\n" );
 
fprintf( fh, "if-not-in-container:PATTERN\n"
 
"\tCapture PATTERN, but only if there is no library of the\n"
 
"\tsame name in the container\n" );
fprintf( fh, "gl:\n"
fprintf( fh, "gl:\n"
"\tShortcut for even-if-older:if-exists:soname:libGL.so.1,\n"
"\tShortcut for even-if-older:if-exists:soname:libGL.so.1,\n"
"\teven-if-older:if-exists:soname-match:libGLX_*.so.0, and\n"
"\teven-if-older:if-exists:soname-match:libGLX_*.so.0, and\n"
@@ -314,6 +317,7 @@ typedef enum
@@ -314,6 +317,7 @@ typedef enum
CAPTURE_FLAG_LIBRARY_ITSELF = ( 1 << 2 ),
CAPTURE_FLAG_LIBRARY_ITSELF = ( 1 << 2 ),
CAPTURE_FLAG_DEPENDENCIES = ( 1 << 3 ),
CAPTURE_FLAG_DEPENDENCIES = ( 1 << 3 ),
CAPTURE_FLAG_IF_SAME_ABI = ( 1 << 4 ),
CAPTURE_FLAG_IF_SAME_ABI = ( 1 << 4 ),
 
CAPTURE_FLAG_IF_NOT_IN_CONTAINER = ( 1 << 5 ),
} capture_flags;
} capture_flags;
typedef struct
typedef struct
@@ -502,6 +506,14 @@ capture_one( const char *soname, const capture_options *options,
@@ -502,6 +506,14 @@ capture_one( const char *soname, const capture_options *options,
library_details details = {};
library_details details = {};
const library_details *known = NULL;
const library_details *known = NULL;
 
if( i == 0 && ( options->flags & CAPTURE_FLAG_IF_NOT_IN_CONTAINER ) )
 
{
 
DEBUG( DEBUG_TOOL,
 
"%s is in the container, ignoring provider version as requested",
 
needed_name );
 
continue;
 
}
 
known = library_knowledge_lookup( &options->knowledge,
known = library_knowledge_lookup( &options->knowledge,
needed_name );
needed_name );
@@ -996,6 +1008,15 @@ capture_pattern( const char *pattern, const capture_options *options,
@@ -996,6 +1008,15 @@ capture_pattern( const char *pattern, const capture_options *options,
&new_options, code, message );
&new_options, code, message );
}
}
 
if( strstarts( pattern, "if-not-in-container:" ) )
 
{
 
capture_options new_options = *options;
 
 
new_options.flags |= CAPTURE_FLAG_IF_NOT_IN_CONTAINER;
 
return capture_pattern( pattern + strlen( "if-not-in-container:" ),
 
&new_options, code, message );
 
}
 
if( strcmp( pattern, "gl:" ) == 0 )
if( strcmp( pattern, "gl:" ) == 0 )
{
{
// Useful information:
// Useful information:
Loading