[libglnx] libcontainer: Pare down to just "run in root" API



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]