Skip to content

Commit ed56961

Browse files
committed
bind-mount /run/opengl-driver/lib
1 parent fe3da3a commit ed56961

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,20 @@ The nix config is not in `/etc/nix` but in `/nix/etc/nix`, so that you can
103103
modify it. This is done with the `NIX_CONF_DIR`, which you can override at any
104104
time.
105105

106+
Libraries and applications from Nixpkgs with OpenGL or CUDA support need to
107+
load libraries from /run/opengl-driver/lib. For convenience, nix-user-chroot
108+
will bind mount /nix/var/nix/opengl-driver/lib (if it exists) to this location.
109+
You will still need to link the system libraries here, as their original
110+
locations are distro-dependent. For example, for CUDA support on Ubuntu 20.04:
111+
112+
```console
113+
$ mkdir -p /nix/var/nix/opengl-driver/lib
114+
$ ln -s /usr/lib/x86_64-linux-gnu/libcuda.so.1 /nix/var/nix/opengl-driver/lib
115+
```
116+
117+
If this directory didn't exist when you first entered the nix user chroot, you
118+
will need to reenter for /run/opengl-driver/lib to be mounted.
119+
106120
## Whishlist
107121

108122
These are features the author would like to see, let me know, if you want to work

src/main.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)