about summary refs log tree commit diff
path: root/pkgs/games/build-support
diff options
context:
space:
mode:
authoraszlig <aszlig@redmoonstudios.org>2017-10-03 23:10:21 +0200
committeraszlig <aszlig@redmoonstudios.org>2017-10-03 23:41:43 +0200
commit175e9328bf9d403c70a0fd3721d1839538558422 (patch)
tree8bc2d87b5616992c3fcab76699e8f1ec54c4dc33 /pkgs/games/build-support
parentb7e0a4c55944b266f2a6c2aa65d093eb31dcc3ad (diff)
pkgs/sandbox: Implement a path cache
First of all this is to bring down the amount of syscalls we're doing
but it's also useful to avoid errors when we try to mount a path over an
already mounted path.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Diffstat (limited to 'pkgs/games/build-support')
-rw-r--r--pkgs/games/build-support/build-sandbox/src/Makefile2
-rw-r--r--pkgs/games/build-support/build-sandbox/src/path-cache.cc21
-rw-r--r--pkgs/games/build-support/build-sandbox/src/path-cache.h10
-rw-r--r--pkgs/games/build-support/build-sandbox/src/setup.c23
4 files changed, 53 insertions, 3 deletions
diff --git a/pkgs/games/build-support/build-sandbox/src/Makefile b/pkgs/games/build-support/build-sandbox/src/Makefile
index f662b5ba..cd642b8e 100644
--- a/pkgs/games/build-support/build-sandbox/src/Makefile
+++ b/pkgs/games/build-support/build-sandbox/src/Makefile
@@ -4,7 +4,7 @@ WRAPPERS = $(subst $(BINDIR),$(out)/bin,$(BINARIES))
 NIX_VERSION = `pkg-config --modversion nix-main | \
                sed -e 's/^\([0-9]\+\)\.\([0-9]\+\).*/\1\2/'`
 
-OBJECTS = nix-query.o params.o setup.o
+OBJECTS = nix-query.o path-cache.o params.o setup.o
 
 CFLAGS = -g -Wall -std=gnu11 -DFS_ROOT_DIR=\"$(out)\"
 CXXFLAGS = -g -Wall -std=c++14 `pkg-config --cflags nix-main`
diff --git a/pkgs/games/build-support/build-sandbox/src/path-cache.cc b/pkgs/games/build-support/build-sandbox/src/path-cache.cc
new file mode 100644
index 00000000..5bfa43a7
--- /dev/null
+++ b/pkgs/games/build-support/build-sandbox/src/path-cache.cc
@@ -0,0 +1,21 @@
+#include <set>
+#include <string>
+
+typedef std::set<std::string> *path_cache;
+
+extern "C" {
+    path_cache new_path_cache(void)
+    {
+        return new std::set<std::string>();
+    }
+
+    void free_path_cache(path_cache pc)
+    {
+        delete pc;
+    }
+
+    bool cache_path(path_cache pc, const char *path)
+    {
+        return pc->insert(std::string(path)).second;
+    }
+}
diff --git a/pkgs/games/build-support/build-sandbox/src/path-cache.h b/pkgs/games/build-support/build-sandbox/src/path-cache.h
new file mode 100644
index 00000000..368f8d17
--- /dev/null
+++ b/pkgs/games/build-support/build-sandbox/src/path-cache.h
@@ -0,0 +1,10 @@
+#ifndef _PATH_CACHE_H
+#define _PATH_CACHE_H
+
+typedef void *path_cache;
+
+path_cache new_path_cache(void);
+void free_path_cache(path_cache pc);
+bool cache_path(path_cache pc, const char *path);
+
+#endif
diff --git a/pkgs/games/build-support/build-sandbox/src/setup.c b/pkgs/games/build-support/build-sandbox/src/setup.c
index 3251a861..b1f8cdcf 100644
--- a/pkgs/games/build-support/build-sandbox/src/setup.c
+++ b/pkgs/games/build-support/build-sandbox/src/setup.c
@@ -19,6 +19,9 @@
 
 #include "params.h"
 #include "nix-query.h"
+#include "path-cache.h"
+
+static path_cache cached_paths = NULL;
 
 static bool write_proc(int proc_pid_fd, const char *fname, const char *buf,
                        size_t buflen, bool ignore_errors)
@@ -106,7 +109,8 @@ static bool makedirs(const char *path)
         }
     }
 
-    (void)mkdir(path, 0755);
+    if (cache_path(cached_paths, path))
+        (void)mkdir(path, 0755);
     free(tmp);
     return true;
 }
@@ -149,6 +153,11 @@ bool bind_mount(const char *path, bool restricted, bool resolve)
         return false;
     }
 
+    if (!cache_path(cached_paths, resolve ? src : path)) {
+        free(target);
+        return true;
+    }
+
     if (mount(resolve ? src : path, target, "", mflags, NULL) == -1) {
         fprintf(stderr, "mount %s to %s: %s\n",
                 resolve ? src : path, target, strerror(errno));
@@ -181,6 +190,11 @@ static bool bind_file(const char *path)
 
     free(tmp);
 
+    if (!cache_path(cached_paths, path)) {
+        free(target);
+        return true;
+    }
+
     if (creat(target, 0666) == -1) {
         fprintf(stderr, "unable to create %s: %s\n", target, strerror(errno));
         free(target);
@@ -640,8 +654,13 @@ bool setup_sandbox(void)
             return false;
     }
 
-    if (!setup_chroot())
+    cached_paths = new_path_cache();
+
+    if (!setup_chroot()) {
+        free_path_cache(cached_paths);
         return false;
+    }
 
+    free_path_cache(cached_paths);
     return true;
 }