]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
tools: move lxc-unshare to API symbols only
authorChristian Brauner <christian.brauner@ubuntu.com>
Fri, 12 Jan 2018 16:06:42 +0000 (17:06 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 6 Feb 2018 20:10:49 +0000 (21:10 +0100)
Closes #2073.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/tools/lxc_unshare.c
src/lxc/tools/tool_utils.c
src/lxc/tools/tool_utils.h

index 9e062a0ca7b068d3daf3dd489d6af2652c33c421..98143d66231cdb81620641fe9587e39a8b51d0db 100644 (file)
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
-#include "config.h"
 
-#include <stdio.h>
+#define _GNU_SOURCE
 #include <errno.h>
+#include <fcntl.h>
 #include <getopt.h>
 #include <libgen.h>
-#include <netinet/in.h>
 #include <pwd.h>
+#include <sched.h>
 #include <signal.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <netinet/in.h>
+#include <unistd.h>
 #include <sys/eventfd.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/wait.h>
-#include <unistd.h>
 
-#include "caps.h"
-#include "cgroup.h"
-#include "error.h"
-#include "log.h"
-#include "namespace.h"
-#include "network.h"
-#include "utils.h"
+#include "arguments.h"
+#include "tool_utils.h"
 
 struct my_iflist
 {
@@ -67,7 +64,7 @@ static void usage(char *cmd)
 
 static bool lookup_user(const char *optarg, uid_t *uid)
 {
-       char name[MAXPATHLEN];
+       char name[TOOL_MAXPATHLEN];
        struct passwd *pwent = NULL;
 
        if (!optarg || (optarg[0] == '\0'))
@@ -147,11 +144,34 @@ static int do_start(void *arg)
        return 1;
 }
 
+int write_id_mapping(pid_t pid, const char *buf, size_t buf_size)
+{
+       char path[TOOL_MAXPATHLEN];
+       int fd, ret;
+
+
+       ret = snprintf(path, TOOL_MAXPATHLEN, "/proc/%d/uid_map", pid);
+       if (ret < 0 || ret >= TOOL_MAXPATHLEN)
+               return -E2BIG;
+
+       fd = open(path, O_WRONLY);
+       if (fd < 0)
+               return -1;
+
+       errno = 0;
+       ret = lxc_write_nointr(fd, buf, buf_size);
+       close(fd);
+       if (ret < 0 || (size_t)ret != buf_size)
+               return -1;
+
+       return 0;
+}
+
 int main(int argc, char *argv[])
 {
        char *del;
        char **it, **args;
-       int opt, status;
+       int opt;
        int ret;
        char *namespaces = NULL;
        int flags = 0, daemonize = 0;
@@ -284,7 +304,7 @@ int main(int argc, char *argv[])
                        exit(EXIT_FAILURE);
                }
 
-               ret = write_id_mapping(ID_TYPE_UID, pid, umap, strlen(umap));
+               ret = write_id_mapping(pid, umap, strlen(umap));
                if (ret < 0) {
                        close(start_arg.wait_fd);
                        fprintf(stderr, "uid mapping failed\n");
@@ -301,19 +321,40 @@ int main(int argc, char *argv[])
 
        if (my_iflist) {
                for (tmpif = my_iflist; tmpif; tmpif = tmpif->mi_next) {
-                       if (lxc_netdev_move_by_name(tmpif->mi_ifname, pid, NULL) < 0)
-                               fprintf(stderr,"Could not move interface %s into container %d: %s\n", tmpif->mi_ifname, pid, strerror(errno));
+                       pid_t pid;
+
+                       pid = fork();
+                       if (pid < 0)
+                               fprintf(stderr, "Failed to move network device "
+                                               "\"%s\" to network namespace\n",
+                                       tmpif->mi_ifname);
+
+                       if (pid == 0) {
+                               char buf[256];
+
+                               ret = snprintf(buf, 256, "%d", pid);
+                               if (ret < 0 || ret >= 256)
+                                       exit(EXIT_FAILURE);
+
+                               execlp("ip", "ip", "link", "set", "dev", tmpif->mi_ifname, "netns", buf, (char *)NULL);
+                               exit(EXIT_FAILURE);
+                       }
+
+                       if (wait_for_pid(pid) != 0)
+                               fprintf(stderr, "Could not move interface %s "
+                                               "into container %d: %s\n",
+                                       tmpif->mi_ifname, pid, strerror(errno));
                }
        }
 
        if (daemonize)
                exit(EXIT_SUCCESS);
 
-       if (waitpid(pid, &status, 0) < 0) {
+       if (wait_for_pid(pid) != 0) {
                fprintf(stderr, "failed to wait for '%d'\n", pid);
                exit(EXIT_FAILURE);
        }
 
        /* Call exit() directly on this function because it retuns an exit code. */
-       exit(lxc_error_set_and_log(pid, status));
+       exit(EXIT_SUCCESS);
 }
index 71b499659098a908cdc3922bcaf996db05b79718..7279b3d4cde3413568dcfd16a2e8f3823b69aff9 100644 (file)
@@ -31,6 +31,7 @@
 #include <strings.h>
 #include <unistd.h>
 #include <linux/sched.h>
+#include <sys/mount.h>
 #include <sys/prctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -42,6 +43,7 @@
 
 #include <lxc/lxccontainer.h>
 
+#include "arguments.h"
 #include "tool_utils.h"
 
 int lxc_fill_elevated_privileges(char *flaglist, int *flags)
@@ -1131,3 +1133,64 @@ again:
                goto again;
        return ret;
 }
+
+static int mount_fs(const char *source, const char *target, const char *type)
+{
+       /* the umount may fail */
+       if (umount(target) < 0)
+
+       if (mount(source, target, type, 0, NULL) < 0)
+               return -1;
+
+       return 0;
+}
+
+void lxc_setup_fs(void)
+{
+       (void)mount_fs("proc", "/proc", "proc");
+
+       /* if /dev has been populated by us, /dev/shm does not exist */
+       if (access("/dev/shm", F_OK))
+               (void)mkdir("/dev/shm", 0777);
+
+       /* if we can't mount /dev/shm, continue anyway */
+       (void)mount_fs("shmfs", "/dev/shm", "tmpfs");
+
+       /* If we were able to mount /dev/shm, then /dev exists */
+       /* Sure, but it's read-only per config :) */
+       if (access("/dev/mqueue", F_OK))
+               (void)mkdir("/dev/mqueue", 0666);
+
+       /* continue even without posix message queue support */
+       (void)mount_fs("mqueue", "/dev/mqueue", "mqueue");
+}
+
+struct clone_arg {
+       int (*fn)(void *);
+       void *arg;
+};
+
+static int do_clone(void *arg)
+{
+       struct clone_arg *clone_arg = arg;
+       return clone_arg->fn(clone_arg->arg);
+}
+
+pid_t lxc_clone(int (*fn)(void *), void *arg, int flags)
+{
+       struct clone_arg clone_arg = {
+               .fn = fn,
+               .arg = arg,
+       };
+
+       size_t stack_size = lxc_getpagesize();
+       void *stack = alloca(stack_size);
+       pid_t ret;
+
+#ifdef __ia64__
+       ret = __clone2(do_clone, stack, stack_size, flags | SIGCHLD, &clone_arg);
+#else
+       ret = clone(do_clone, stack  + stack_size, flags | SIGCHLD, &clone_arg);
+#endif
+       return ret;
+}
index 278402ab3a42d011efef8bb262b76ffae178d44f..b93713714047161ad807283bdb21cdeff4909938 100644 (file)
@@ -176,4 +176,28 @@ extern ssize_t lxc_write_nointr(int fd, const void* buf, size_t count);
 
 extern char *get_rundir();
 
+extern void lxc_setup_fs(void);
+
+static inline uint64_t lxc_getpagesize(void)
+{
+       int64_t pgsz;
+
+       pgsz = sysconf(_SC_PAGESIZE);
+       if (pgsz <= 0)
+               pgsz = 1 << 12;
+
+       return pgsz;
+}
+
+#if defined(__ia64__)
+int __clone2(int (*__fn) (void *__arg), void *__child_stack_base,
+             size_t __child_stack_size, int __flags, void *__arg, ...);
+#else
+int clone(int (*fn)(void *), void *child_stack,
+       int flags, void *arg, ...
+       /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
+#endif
+
+extern pid_t lxc_clone(int (*fn)(void *), void *arg, int flags);
+
 #endif /* __LXC_UTILS_H */