From 175e9328bf9d403c70a0fd3721d1839538558422 Mon Sep 17 00:00:00 2001 From: aszlig Date: Tue, 3 Oct 2017 23:10:21 +0200 Subject: 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 --- .../games/build-support/build-sandbox/src/Makefile | 2 +- .../build-support/build-sandbox/src/path-cache.cc | 21 ++++++++++++++++++++ .../build-support/build-sandbox/src/path-cache.h | 10 ++++++++++ pkgs/games/build-support/build-sandbox/src/setup.c | 23 ++++++++++++++++++++-- 4 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 pkgs/games/build-support/build-sandbox/src/path-cache.cc create mode 100644 pkgs/games/build-support/build-sandbox/src/path-cache.h (limited to 'pkgs/games/build-support') 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 +#include + +typedef std::set *path_cache; + +extern "C" { + path_cache new_path_cache(void) + { + return new std::set(); + } + + 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; } -- cgit 1.4.1