[libglnx] libcontainer: Pare down to just "run in root" API
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libglnx] libcontainer: Pare down to just "run in root" API
- Date: Mon, 24 Aug 2015 20:16:45 +0000 (UTC)
commit fbdb15cd958c007dc14f6e7cfe314b14c042ce3c
Author: Colin Walters <walters verbum org>
Date: Mon Aug 24 13:44:50 2015 -0400
libcontainer: Pare down to just "run in root" API
rpm-ostree is going through some awkwardness trying to
support being run both inside and outside of a container.
For now, let's drop all recursive container usage. There is still
some value in readding this in the future - for example, downloading
packages requires networking, but `%post` scripts do not. But we
should really solve that when we return to running unprivileged or the
like.
glnx-libcontainer.c | 62 ++++++++++++++++++++++++++++++++------------------
glnx-libcontainer.h | 14 ++---------
2 files changed, 43 insertions(+), 33 deletions(-)
---
diff --git a/glnx-libcontainer.c b/glnx-libcontainer.c
index 3f50007..b4e93e7 100644
--- a/glnx-libcontainer.c
+++ b/glnx-libcontainer.c
@@ -37,8 +37,6 @@
#include "glnx-backport-autocleanups.h"
#include "glnx-local-alloc.h"
-static gboolean container_available = TRUE;
-
static void _perror_fatal (const char *message) __attribute__ ((noreturn));
static void
@@ -48,19 +46,35 @@ _perror_fatal (const char *message)
exit (1);
}
-void
-glnx_libcontainer_set_not_available (void)
-{
- container_available = FALSE;
-}
+typedef enum {
+ CONTAINER_UNINIT = 0,
+ CONTAINER_YES = 1,
+ CONTAINER_NO = 2
+} ContainerDetectionState;
-gboolean
-glnx_libcontainer_get_available (void)
+static gboolean
+currently_in_container (void)
{
- return container_available;
+ static gsize container_detected = CONTAINER_UNINIT;
+
+ if (g_once_init_enter (&container_detected))
+ {
+ ContainerDetectionState tmp_state = CONTAINER_NO;
+ struct stat stbuf;
+
+ /* http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface/ */
+ if (getenv ("container") != NULL
+ || stat ("/.dockerinit", &stbuf) == 0)
+ tmp_state = CONTAINER_YES;
+ /* But since Docker isn't on board, yet, so...
+
http://stackoverflow.com/questions/23513045/how-to-check-if-a-process-is-running-inside-docker-container */
+ g_once_init_leave (&container_detected, tmp_state);
+ }
+ return container_detected == CONTAINER_YES;
}
-gboolean
+#if 0
+static gboolean
glnx_libcontainer_bind_mount_readonly (const char *path, GError **error)
{
gboolean ret = FALSE;
@@ -88,10 +102,10 @@ glnx_libcontainer_bind_mount_readonly (const char *path, GError **error)
out:
return ret;
}
-
+#endif
/* Based on code from nspawn.c */
-int
+static int
glnx_libcontainer_make_api_mounts (const char *dest)
{
typedef struct MountPoint {
@@ -148,7 +162,7 @@ glnx_libcontainer_make_api_mounts (const char *dest)
return 0;
}
-int
+static int
glnx_libcontainer_prep_dev (const char *dest_devdir)
{
glnx_fd_close int src_fd = -1;
@@ -187,15 +201,19 @@ glnx_libcontainer_prep_dev (const char *dest_devdir)
}
pid_t
-glnx_libcontainer_run_in_root (const char *dest,
- const char *binary,
- char **argv)
+glnx_libcontainer_run_chroot_private (const char *dest,
+ const char *binary,
+ char **argv)
{
+ /* Make most new namespaces; note our use of CLONE_NEWNET means we
+ * have no networking in the container root.
+ */
const int cloneflags =
SIGCHLD | CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | CLONE_SYSVSEM | CLONE_NEWUTS;
pid_t child;
+ gboolean in_container = currently_in_container ();
- if (container_available)
+ if (!in_container)
{
if ((child = syscall (__NR_clone, cloneflags, NULL)) < 0)
return -1;
@@ -209,7 +227,7 @@ glnx_libcontainer_run_in_root (const char *dest,
if (child != 0)
return child;
- if (container_available)
+ if (!in_container)
{
if (mount (NULL, "/", "none", MS_PRIVATE | MS_REC, NULL) != 0)
{
@@ -219,13 +237,13 @@ glnx_libcontainer_run_in_root (const char *dest,
* that case, let's just fall back to not
* containerizing.
*/
- container_available = FALSE;
+ in_container = TRUE;
}
else
_perror_fatal ("mount: ");
}
- if (container_available)
+ if (!in_container)
{
if (mount (NULL, "/", "none", MS_PRIVATE | MS_REMOUNT | MS_NOSUID, NULL) != 0)
_perror_fatal ("mount (MS_NOSUID): ");
@@ -235,7 +253,7 @@ glnx_libcontainer_run_in_root (const char *dest,
if (chdir (dest) != 0)
_perror_fatal ("chdir: ");
- if (container_available)
+ if (!in_container)
{
if (glnx_libcontainer_make_api_mounts (dest) != 0)
_perror_fatal ("preparing api mounts: ");
diff --git a/glnx-libcontainer.h b/glnx-libcontainer.h
index 16cdb65..10855db 100644
--- a/glnx-libcontainer.h
+++ b/glnx-libcontainer.h
@@ -31,14 +31,6 @@
#include <sys/capability.h>
#include <sched.h>
-void glnx_libcontainer_set_not_available (void);
-gboolean glnx_libcontainer_get_available (void);
-
-gboolean glnx_libcontainer_bind_mount_readonly (const char *path, GError **error);
-
-int glnx_libcontainer_make_api_mounts (const char *dest);
-int glnx_libcontainer_prep_dev (const char *dest);
-
-pid_t glnx_libcontainer_run_in_root (const char *dest,
- const char *binary,
- char **argv);
+pid_t glnx_libcontainer_run_chroot_private (const char *dest,
+ const char *binary,
+ char **argv);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]