summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2016-08-07 07:21:55 -0400
committerColin Walters <walters@verbum.org>2016-08-07 07:29:48 -0400
commit4ae5e3beaaa674abfabf7404ab6fafcc4ec547db (patch)
treed96a8adab29768d407bbdff4427158954eee85a9
parent871617d51984604e28483d959e37fd6ce4524b0e (diff)
downloadlibglnx-4ae5e3beaaa674abfabf7404ab6fafcc4ec547db.tar.gz
libcontainer: Add a fd-relative API
I'm porting rpm-ostree and need this. Of course all this libcontainer stuff will be nuked in favor of bubblewrap when everything comes together.
-rw-r--r--glnx-libcontainer.c38
-rw-r--r--glnx-libcontainer.h4
2 files changed, 31 insertions, 11 deletions
diff --git a/glnx-libcontainer.c b/glnx-libcontainer.c
index 38c1937..6b9a2d6 100644
--- a/glnx-libcontainer.c
+++ b/glnx-libcontainer.c
@@ -33,6 +33,7 @@
#include <gio/gunixoutputstream.h>
#include "glnx-libcontainer.h"
+#include "glnx-dirfd.h"
#include "glnx-backport-autocleanups.h"
#include "glnx-local-alloc.h"
@@ -104,9 +105,9 @@ glnx_libcontainer_bind_mount_readonly (const char *path, GError **error)
}
#endif
-/* Based on code from nspawn.c */
+/* Based on code from nspawn.c; assumes process cwd is the target */
static int
-glnx_libcontainer_make_api_mounts (const char *dest)
+glnx_libcontainer_make_api_mounts (void)
{
typedef struct MountPoint {
const char *what;
@@ -134,10 +135,11 @@ glnx_libcontainer_make_api_mounts (const char *dest)
for (k = 0; k < G_N_ELEMENTS(mount_table); k++)
{
- g_autofree char *where = NULL;
+ const char *where = mount_table[k].where;
int t;
- where = g_build_filename (dest, mount_table[k].where, NULL);
+ g_assert (where[0] == '/');
+ where++;
t = mkdir (where, 0755);
if (t < 0 && errno != EEXIST)
@@ -201,9 +203,9 @@ glnx_libcontainer_prep_dev (const char *dest_devdir)
}
pid_t
-glnx_libcontainer_run_chroot_private (const char *dest,
- const char *binary,
- char **argv)
+glnx_libcontainer_run_chroot_at_private (int dfd,
+ const char *binary,
+ char **argv)
{
/* Make most new namespaces; note our use of CLONE_NEWNET means we
* have no networking in the container root.
@@ -250,12 +252,12 @@ glnx_libcontainer_run_chroot_private (const char *dest,
}
}
- if (chdir (dest) != 0)
- _perror_fatal ("chdir: ");
+ if (fchdir (dfd) != 0)
+ _perror_fatal ("fchdir: ");
if (!in_container)
{
- if (glnx_libcontainer_make_api_mounts (dest) != 0)
+ if (glnx_libcontainer_make_api_mounts () != 0)
_perror_fatal ("preparing api mounts: ");
if (glnx_libcontainer_prep_dev ("dev") != 0)
@@ -264,7 +266,7 @@ glnx_libcontainer_run_chroot_private (const char *dest,
if (mount (".", ".", NULL, MS_BIND | MS_PRIVATE, NULL) != 0)
_perror_fatal ("mount (MS_BIND)");
- if (mount (dest, "/", NULL, MS_MOVE, NULL) != 0)
+ if (mount (".", "/", NULL, MS_MOVE, NULL) != 0)
_perror_fatal ("mount (MS_MOVE)");
}
@@ -295,3 +297,17 @@ glnx_libcontainer_run_chroot_private (const char *dest,
g_assert_not_reached ();
}
+
+pid_t
+glnx_libcontainer_run_chroot_private (const char *dest,
+ const char *binary,
+ char **argv)
+{
+ glnx_fd_close int dfd = -1;
+
+ dfd = glnx_opendirat_with_errno (AT_FDCWD, dest, TRUE);
+ if (dfd < 0)
+ return -1;
+
+ return glnx_libcontainer_run_chroot_at_private (dfd, binary, argv);
+}
diff --git a/glnx-libcontainer.h b/glnx-libcontainer.h
index 10855db..9ac83d4 100644
--- a/glnx-libcontainer.h
+++ b/glnx-libcontainer.h
@@ -31,6 +31,10 @@
#include <sys/capability.h>
#include <sched.h>
+pid_t glnx_libcontainer_run_chroot_at_private (int root_dfd,
+ const char *binary,
+ char **argv);
+
pid_t glnx_libcontainer_run_chroot_private (const char *dest,
const char *binary,
char **argv);