@@ -46,13 +46,27 @@ impl<'a> RunChroot<'a> {
4646
4747 fn bind_mount_directory ( & self , entry : & fs:: DirEntry ) {
4848 let mountpoint = self . rootdir . join ( entry. file_name ( ) ) ;
49- if let Err ( e) = fs:: create_dir ( & mountpoint) {
50- if e. kind ( ) != io:: ErrorKind :: AlreadyExists {
51- panic ! ( "failed to create {}: {}" , & mountpoint. display( ) , e) ;
49+
50+ // if there is already a dir here, recurse into it,
51+ // and mount any subdirs which don't already exist
52+ if mountpoint. is_dir ( ) {
53+ let dir = fs:: read_dir ( entry. path ( ) ) . unwrap_or_else ( |err| {
54+ panic ! ( "failed to list dir {}: {}" , entry. path( ) . display( ) , err)
55+ } ) ;
56+
57+ let child = RunChroot :: new ( & mountpoint) ;
58+ for entry in dir {
59+ child. bind_mount_direntry ( entry) ;
60+ }
61+ } else {
62+ if let Err ( e) = fs:: create_dir ( & mountpoint) {
63+ if e. kind ( ) != io:: ErrorKind :: AlreadyExists {
64+ panic ! ( "failed to create {}: {}" , & mountpoint. display( ) , e) ;
65+ }
5266 }
53- }
5467
55- bind_mount ( & entry. path ( ) , & mountpoint)
68+ bind_mount ( & entry. path ( ) , & mountpoint)
69+ }
5670 }
5771
5872 fn bind_mount_file ( & self , entry : & fs:: DirEntry ) {
@@ -104,7 +118,17 @@ impl<'a> RunChroot<'a> {
104118
105119 unshare ( CloneFlags :: CLONE_NEWNS | CloneFlags :: CLONE_NEWUSER ) . expect ( "unshare failed" ) ;
106120
107- // bind mount all / stuff into rootdir
121+ // create /run/opengl-driver/lib in chroot, to behave like NixOS
122+ // (needed for nix pkgs with OpenGL or CUDA support to work)
123+ let ogldir = nixdir. join ( "var/nix/opengl-driver/lib" ) ;
124+ if ogldir. is_dir ( ) {
125+ let ogl_mount = self . rootdir . join ( "run/opengl-driver/lib" ) ;
126+ fs:: create_dir_all ( & ogl_mount)
127+ . unwrap_or_else ( |err| panic ! ( "failed to create {}: {}" , & ogl_mount. display( ) , err) ) ;
128+ bind_mount ( & ogldir, & ogl_mount) ;
129+ }
130+
131+ // bind the rest of / stuff into rootdir
108132 let nix_root = PathBuf :: from ( "/" ) ;
109133 let dir = fs:: read_dir ( & nix_root) . expect ( "failed to list /nix directory" ) ;
110134 for entry in dir {
0 commit comments