]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxc-destroy: remove btrfs subvolumes
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Tue, 28 Apr 2015 13:31:05 +0000 (13:31 +0000)
committerStéphane Graber <stgraber@ubuntu.com>
Wed, 1 Jul 2015 16:55:09 +0000 (12:55 -0400)
Doing this requires some btrfs functions from bdev to be used in
utils.c  Because utils.h is imported by lxc_init.c, I had to create
a new initutils.[ch] which are used by both lxc_init.c and utils.c
We could instead put the btrfs functions into utils.c, which would
be a shorter patch, but it really doesn't belong there.  So I went
the other way figuring there may be more such cases coming up of
fns in utils.c needing code from bdev.c which can't go into lxc_init.

Currently, if we detect a btrfs subvolume we just remove it.  The
st_dev on that dir is different, so we cannot detect if this is
bound in from another fs easily.  If we care, we should check
whether this is a mountpoint, this patch doesn't do that.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
src/lxc/Makefile.am
src/lxc/bdev.c
src/lxc/bdev.h
src/lxc/initutils.c [new file with mode: 0644]
src/lxc/initutils.h [new file with mode: 0644]
src/lxc/lxc_init.c
src/lxc/utils.c
src/lxc/utils.h

index 6778a1917c261b49aa0b0aa7087fef1e8013cfa0..ce464950de15bb8310784a09edfca68c3671cd56 100644 (file)
@@ -12,6 +12,7 @@ noinst_HEADERS = \
        conf.h \
        console.h \
        error.h \
+       initutils.h \
        list.h \
        log.h \
        lxc.h \
@@ -67,6 +68,7 @@ liblxc_so_SOURCES = \
        cgfs.c \
        cgroup.c cgroup.h \
        lxc.h \
+       initutils.c initutils.h \
        utils.c utils.h \
        sync.c sync.h \
        namespace.h namespace.c \
@@ -239,7 +241,7 @@ lxc_checkpoint_SOURCES = lxc_checkpoint.c
 if HAVE_STATIC_LIBCAP
 sbin_PROGRAMS += init.lxc.static
 
-init_lxc_static_SOURCES = lxc_init.c error.c log.c utils.c caps.c
+init_lxc_static_SOURCES = lxc_init.c error.c log.c initutils.c caps.c
 
 if !HAVE_GETLINE
 if HAVE_FGETLN
index 95d10a49f7eaf36a944938120f4256086c9edc31..d45b21690e2d04ed96af752d248fd70f8100a9dd 100644 (file)
@@ -1253,7 +1253,7 @@ int btrfs_list_get_path_rootid(int fd, u64 *treeid)
        return 0;
 }
 
-static bool is_btrfs_fs(const char *path)
+bool is_btrfs_fs(const char *path)
 {
        int fd, ret;
        struct btrfs_ioctl_space_args sargs;
@@ -1531,7 +1531,7 @@ static int btrfs_do_destroy_subvol(const char *path)
 
        fd = open(newfull, O_RDONLY);
        if (fd < 0) {
-               ERROR("Error opening %s", newfull);
+               SYSERROR("Error opening %s", newfull);
                free(newfull);
                return -1;
        }
@@ -1829,6 +1829,13 @@ ignore_search:
        return btrfs_do_destroy_subvol(path);
 }
 
+bool btrfs_try_remove_subvol(const char *path)
+{
+       if (!btrfs_detect(path))
+               return false;
+       return btrfs_recursive_destroy(path) == 0;
+}
+
 static int btrfs_destroy(struct bdev *orig)
 {
        return btrfs_recursive_destroy(orig->src);
index d97b9df42fe38d53b23c3a6f6e05d9e2b0564d01..2144c1926b595b45a2d9f107f59622b96357d574 100644 (file)
@@ -105,30 +105,4 @@ bool attach_block_device(struct lxc_conf *conf);
 void detach_block_device(struct lxc_conf *conf);
 
 bool rootfs_is_blockdev(struct lxc_conf *conf);
-
-/* define constants if the kernel/glibc headers don't define them */
-#ifndef MS_DIRSYNC
-#define MS_DIRSYNC  128
-#endif
-
-#ifndef MS_REC
-#define MS_REC 16384
-#endif
-
-#ifndef MNT_DETACH
-#define MNT_DETACH 2
-#endif
-
-#ifndef MS_SLAVE
-#define MS_SLAVE (1<<19)
-#endif
-
-#ifndef MS_RELATIME
-#define MS_RELATIME (1 << 21)
-#endif
-
-#ifndef MS_STRICTATIME
-#define MS_STRICTATIME (1 << 24)
-#endif
-
 #endif
diff --git a/src/lxc/initutils.c b/src/lxc/initutils.c
new file mode 100644 (file)
index 0000000..dbb5d52
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <daniel.lezcano at free.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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 "initutils.h"
+#include "log.h"
+
+lxc_log_define(lxc_initutils, lxc);
+
+static int mount_fs(const char *source, const char *target, const char *type)
+{
+       /* the umount may fail */
+       if (umount(target))
+               WARN("failed to unmount %s : %s", target, strerror(errno));
+
+       if (mount(source, target, type, 0, NULL)) {
+               ERROR("failed to mount %s : %s", target, strerror(errno));
+               return -1;
+       }
+
+       DEBUG("'%s' mounted on '%s'", source, target);
+
+       return 0;
+}
+
+extern void lxc_setup_fs(void)
+{
+       if (mount_fs("proc", "/proc", "proc"))
+               INFO("failed to remount proc");
+
+       /* if we can't mount /dev/shm, continue anyway */
+       if (mount_fs("shmfs", "/dev/shm", "tmpfs"))
+               INFO("failed to mount /dev/shm");
+
+       /* 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) && mkdir("/dev/mqueue", 0666)) {
+               DEBUG("failed to create '/dev/mqueue'");
+               return;
+       }
+
+       /* continue even without posix message queue support */
+       if (mount_fs("mqueue", "/dev/mqueue", "mqueue"))
+               INFO("failed to mount /dev/mqueue");
+}
+
+static char *copy_global_config_value(char *p)
+{
+       int len = strlen(p);
+       char *retbuf;
+
+       if (len < 1)
+               return NULL;
+       if (p[len-1] == '\n') {
+               p[len-1] = '\0';
+               len--;
+       }
+       retbuf = malloc(len+1);
+       if (!retbuf)
+               return NULL;
+       strcpy(retbuf, p);
+       return retbuf;
+}
+
+const char *lxc_global_config_value(const char *option_name)
+{
+       static const char * const options[][2] = {
+               { "lxc.bdev.lvm.vg",        DEFAULT_VG      },
+               { "lxc.bdev.lvm.thin_pool", DEFAULT_THIN_POOL },
+               { "lxc.bdev.zfs.root",      DEFAULT_ZFSROOT },
+               { "lxc.lxcpath",            NULL            },
+               { "lxc.default_config",     NULL            },
+               { "lxc.cgroup.pattern",     NULL            },
+               { "lxc.cgroup.use",         NULL            },
+               { NULL, NULL },
+       };
+
+       /* placed in the thread local storage pool for non-bionic targets */
+#ifdef HAVE_TLS
+       static __thread const char *values[sizeof(options) / sizeof(options[0])] = { 0 };
+#else
+       static const char *values[sizeof(options) / sizeof(options[0])] = { 0 };
+#endif
+
+       /* user_config_path is freed as soon as it is used */
+       char *user_config_path = NULL;
+
+       /*
+        * The following variables are freed at bottom unconditionally.
+        * So NULL the value if it is to be returned to the caller
+        */
+       char *user_default_config_path = NULL;
+       char *user_lxc_path = NULL;
+       char *user_cgroup_pattern = NULL;
+
+       if (geteuid() > 0) {
+               const char *user_home = getenv("HOME");
+               if (!user_home)
+                       user_home = "/";
+
+               user_config_path = malloc(sizeof(char) * (22 + strlen(user_home)));
+               user_default_config_path = malloc(sizeof(char) * (26 + strlen(user_home)));
+               user_lxc_path = malloc(sizeof(char) * (19 + strlen(user_home)));
+
+               sprintf(user_config_path, "%s/.config/lxc/lxc.conf", user_home);
+               sprintf(user_default_config_path, "%s/.config/lxc/default.conf", user_home);
+               sprintf(user_lxc_path, "%s/.local/share/lxc/", user_home);
+               user_cgroup_pattern = strdup("lxc/%n");
+       }
+       else {
+               user_config_path = strdup(LXC_GLOBAL_CONF);
+               user_default_config_path = strdup(LXC_DEFAULT_CONFIG);
+               user_lxc_path = strdup(LXCPATH);
+               user_cgroup_pattern = strdup(DEFAULT_CGROUP_PATTERN);
+       }
+
+       const char * const (*ptr)[2];
+       size_t i;
+       char buf[1024], *p, *p2;
+       FILE *fin = NULL;
+
+       for (i = 0, ptr = options; (*ptr)[0]; ptr++, i++) {
+               if (!strcmp(option_name, (*ptr)[0]))
+                       break;
+       }
+       if (!(*ptr)[0]) {
+               free(user_config_path);
+               free(user_default_config_path);
+               free(user_lxc_path);
+               free(user_cgroup_pattern);
+               errno = EINVAL;
+               return NULL;
+       }
+
+       if (values[i]) {
+               free(user_config_path);
+               free(user_default_config_path);
+               free(user_lxc_path);
+               free(user_cgroup_pattern);
+               return values[i];
+       }
+
+       fin = fopen_cloexec(user_config_path, "r");
+       free(user_config_path);
+       if (fin) {
+               while (fgets(buf, 1024, fin)) {
+                       if (buf[0] == '#')
+                               continue;
+                       p = strstr(buf, option_name);
+                       if (!p)
+                               continue;
+                       /* see if there was just white space in front
+                        * of the option name
+                        */
+                       for (p2 = buf; p2 < p; p2++) {
+                               if (*p2 != ' ' && *p2 != '\t')
+                                       break;
+                       }
+                       if (p2 < p)
+                               continue;
+                       p = strchr(p, '=');
+                       if (!p)
+                               continue;
+                       /* see if there was just white space after
+                        * the option name
+                        */
+                       for (p2 += strlen(option_name); p2 < p; p2++) {
+                               if (*p2 != ' ' && *p2 != '\t')
+                                       break;
+                       }
+                       if (p2 < p)
+                               continue;
+                       p++;
+                       while (*p && (*p == ' ' || *p == '\t')) p++;
+                       if (!*p)
+                               continue;
+
+                       if (strcmp(option_name, "lxc.lxcpath") == 0) {
+                               free(user_lxc_path);
+                               user_lxc_path = copy_global_config_value(p);
+                               remove_trailing_slashes(user_lxc_path);
+                               values[i] = user_lxc_path;
+                               user_lxc_path = NULL;
+                               goto out;
+                       }
+
+                       values[i] = copy_global_config_value(p);
+                       goto out;
+               }
+       }
+       /* could not find value, use default */
+       if (strcmp(option_name, "lxc.lxcpath") == 0) {
+               remove_trailing_slashes(user_lxc_path);
+               values[i] = user_lxc_path;
+               user_lxc_path = NULL;
+       }
+       else if (strcmp(option_name, "lxc.default_config") == 0) {
+               values[i] = user_default_config_path;
+               user_default_config_path = NULL;
+       }
+       else if (strcmp(option_name, "lxc.cgroup.pattern") == 0) {
+               values[i] = user_cgroup_pattern;
+               user_cgroup_pattern = NULL;
+       }
+       else
+               values[i] = (*ptr)[1];
+
+       /* special case: if default value is NULL,
+        * and there is no config, don't view that
+        * as an error... */
+       if (!values[i])
+               errno = 0;
+
+out:
+       if (fin)
+               fclose(fin);
+
+       free(user_cgroup_pattern);
+       free(user_default_config_path);
+       free(user_lxc_path);
+
+       return values[i];
+}
+
+extern void remove_trailing_slashes(char *p)
+{
+       int l = strlen(p);
+       while (--l >= 0 && (p[l] == '/' || p[l] == '\n'))
+               p[l] = '\0';
+}
+
+FILE *fopen_cloexec(const char *path, const char *mode)
+{
+       int open_mode = 0;
+       int step = 0;
+       int fd;
+       int saved_errno = 0;
+       FILE *ret;
+
+       if (!strncmp(mode, "r+", 2)) {
+               open_mode = O_RDWR;
+               step = 2;
+       } else if (!strncmp(mode, "r", 1)) {
+               open_mode = O_RDONLY;
+               step = 1;
+       } else if (!strncmp(mode, "w+", 2)) {
+               open_mode = O_RDWR | O_TRUNC | O_CREAT;
+               step = 2;
+       } else if (!strncmp(mode, "w", 1)) {
+               open_mode = O_WRONLY | O_TRUNC | O_CREAT;
+               step = 1;
+       } else if (!strncmp(mode, "a+", 2)) {
+               open_mode = O_RDWR | O_CREAT | O_APPEND;
+               step = 2;
+       } else if (!strncmp(mode, "a", 1)) {
+               open_mode = O_WRONLY | O_CREAT | O_APPEND;
+               step = 1;
+       }
+       for (; mode[step]; step++)
+               if (mode[step] == 'x')
+                       open_mode |= O_EXCL;
+       open_mode |= O_CLOEXEC;
+
+       fd = open(path, open_mode, 0666);
+       if (fd < 0)
+               return NULL;
+
+       ret = fdopen(fd, mode);
+       saved_errno = errno;
+       if (!ret)
+               close(fd);
+       errno = saved_errno;
+       return ret;
+}
diff --git a/src/lxc/initutils.h b/src/lxc/initutils.h
new file mode 100644 (file)
index 0000000..b4f9e54
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <daniel.lezcano at free.fr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __LXC_INITUTILS_H
+#define __LXC_INITUTILS_H
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+
+#include "config.h"
+
+#define DEFAULT_VG "lxc"
+#define DEFAULT_THIN_POOL "lxc"
+#define DEFAULT_ZFSROOT "lxc"
+
+extern void lxc_setup_fs(void);
+extern const char *lxc_global_config_value(const char *option_name);
+
+/* open a file with O_CLOEXEC */
+extern void remove_trailing_slashes(char *p);
+FILE *fopen_cloexec(const char *path, const char *mode);
+
+#endif /* __LXC_INITUTILS_H */
index 0778bfe5d211413b349f9cdb8597b9ea0d45ef80..62ed4ad1b14a79c70fe42559affc94f248621a99 100644 (file)
@@ -36,7 +36,7 @@
 #include "log.h"
 #include "caps.h"
 #include "error.h"
-#include "utils.h"
+#include "initutils.h"
 
 lxc_log_define(lxc_init, lxc);
 
index fe71e9aa454ce747b9912e6da3a471eac8171314..e597725f55cd1d4107189a0d56fd871b0af2300b 100644 (file)
 
 lxc_log_define(lxc_utils, lxc);
 
+/*
+ * if path is btrfs, tries to remove it and any subvolumes beneath it
+ */
+extern bool btrfs_try_remove_subvol(const char *path);
+
 static int _recursive_rmdir(char *dirname, dev_t pdev,
                            const char *exclude, int level, bool onedev)
 {
@@ -127,11 +132,16 @@ static int _recursive_rmdir(char *dirname, dev_t pdev,
                ret = lstat(pathname, &mystat);
                if (ret) {
                        ERROR("%s: failed to stat %s", __func__, pathname);
-                       failed=1;
+                       failed = 1;
                        continue;
                }
-               if (onedev && mystat.st_dev != pdev)
+               if (onedev && mystat.st_dev != pdev) {
+                       /* TODO should we be checking /proc/self/mountinfo for
+                        * pathname and not doing this if found? */
+                       if (btrfs_try_remove_subvol(pathname))
+                               INFO("Removed btrfs subvolume at %s\n", pathname);
                        continue;
+               }
                if (S_ISDIR(mystat.st_mode)) {
                        if (_recursive_rmdir(pathname, pdev, exclude, level+1, onedev) < 0)
                                failed=1;
@@ -143,11 +153,9 @@ static int _recursive_rmdir(char *dirname, dev_t pdev,
                }
        }
 
-       if (rmdir(dirname) < 0) {
-               if (!hadexclude) {
-                       ERROR("%s: failed to delete %s", __func__, dirname);
-                       failed=1;
-               }
+       if (rmdir(dirname) < 0 && !btrfs_try_remove_subvol(dirname) && !hadexclude) {
+               ERROR("%s: failed to delete %s", __func__, dirname);
+               failed=1;
        }
 
        ret = closedir(dir);
@@ -196,43 +204,6 @@ extern int lxc_rmdir_onedev(char *path, const char *exclude)
        return _recursive_rmdir(path, mystat.st_dev, exclude, 0, onedev);
 }
 
-static int mount_fs(const char *source, const char *target, const char *type)
-{
-       /* the umount may fail */
-       if (umount(target))
-               WARN("failed to unmount %s : %s", target, strerror(errno));
-
-       if (mount(source, target, type, 0, NULL)) {
-               ERROR("failed to mount %s : %s", target, strerror(errno));
-               return -1;
-       }
-
-       DEBUG("'%s' mounted on '%s'", source, target);
-
-       return 0;
-}
-
-extern void lxc_setup_fs(void)
-{
-       if (mount_fs("proc", "/proc", "proc"))
-               INFO("failed to remount proc");
-
-       /* if we can't mount /dev/shm, continue anyway */
-       if (mount_fs("shmfs", "/dev/shm", "tmpfs"))
-               INFO("failed to mount /dev/shm");
-
-       /* 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) && mkdir("/dev/mqueue", 0666)) {
-               DEBUG("failed to create '/dev/mqueue'");
-               return;
-       }
-
-       /* continue even without posix message queue support */
-       if (mount_fs("mqueue", "/dev/mqueue", "mqueue"))
-               INFO("failed to mount /dev/mqueue");
-}
-
 /* borrowed from iproute2 */
 extern int get_u16(unsigned short *val, const char *arg, int base)
 {
@@ -275,195 +246,6 @@ extern int mkdir_p(const char *dir, mode_t mode)
        return 0;
 }
 
-extern void remove_trailing_slashes(char *p)
-{
-       int l = strlen(p);
-       while (--l >= 0 && (p[l] == '/' || p[l] == '\n'))
-               p[l] = '\0';
-}
-
-static char *copy_global_config_value(char *p)
-{
-       int len = strlen(p);
-       char *retbuf;
-
-       if (len < 1)
-               return NULL;
-       if (p[len-1] == '\n') {
-               p[len-1] = '\0';
-               len--;
-       }
-       retbuf = malloc(len+1);
-       if (!retbuf)
-               return NULL;
-       strcpy(retbuf, p);
-       return retbuf;
-}
-
-#define DEFAULT_VG "lxc"
-#define DEFAULT_THIN_POOL "lxc"
-#define DEFAULT_ZFSROOT "lxc"
-
-const char *lxc_global_config_value(const char *option_name)
-{
-       static const char * const options[][2] = {
-               { "lxc.bdev.lvm.vg",        DEFAULT_VG      },
-               { "lxc.bdev.lvm.thin_pool", DEFAULT_THIN_POOL },
-               { "lxc.bdev.zfs.root",      DEFAULT_ZFSROOT },
-               { "lxc.lxcpath",            NULL            },
-               { "lxc.default_config",     NULL            },
-               { "lxc.cgroup.pattern",     NULL            },
-               { "lxc.cgroup.use",         NULL            },
-               { NULL, NULL },
-       };
-
-       /* placed in the thread local storage pool for non-bionic targets */
-#ifdef HAVE_TLS
-       static __thread const char *values[sizeof(options) / sizeof(options[0])] = { 0 };
-#else
-       static const char *values[sizeof(options) / sizeof(options[0])] = { 0 };
-#endif
-
-       /* user_config_path is freed as soon as it is used */
-       char *user_config_path = NULL;
-
-       /*
-        * The following variables are freed at bottom unconditionally.
-        * So NULL the value if it is to be returned to the caller
-        */
-       char *user_default_config_path = NULL;
-       char *user_lxc_path = NULL;
-       char *user_cgroup_pattern = NULL;
-
-       if (geteuid() > 0) {
-               const char *user_home = getenv("HOME");
-               if (!user_home)
-                       user_home = "/";
-
-               user_config_path = malloc(sizeof(char) * (22 + strlen(user_home)));
-               user_default_config_path = malloc(sizeof(char) * (26 + strlen(user_home)));
-               user_lxc_path = malloc(sizeof(char) * (19 + strlen(user_home)));
-
-               sprintf(user_config_path, "%s/.config/lxc/lxc.conf", user_home);
-               sprintf(user_default_config_path, "%s/.config/lxc/default.conf", user_home);
-               sprintf(user_lxc_path, "%s/.local/share/lxc/", user_home);
-               user_cgroup_pattern = strdup("lxc/%n");
-       }
-       else {
-               user_config_path = strdup(LXC_GLOBAL_CONF);
-               user_default_config_path = strdup(LXC_DEFAULT_CONFIG);
-               user_lxc_path = strdup(LXCPATH);
-               user_cgroup_pattern = strdup(DEFAULT_CGROUP_PATTERN);
-       }
-
-       const char * const (*ptr)[2];
-       size_t i;
-       char buf[1024], *p, *p2;
-       FILE *fin = NULL;
-
-       for (i = 0, ptr = options; (*ptr)[0]; ptr++, i++) {
-               if (!strcmp(option_name, (*ptr)[0]))
-                       break;
-       }
-       if (!(*ptr)[0]) {
-               free(user_config_path);
-               free(user_default_config_path);
-               free(user_lxc_path);
-               free(user_cgroup_pattern);
-               errno = EINVAL;
-               return NULL;
-       }
-
-       if (values[i]) {
-               free(user_config_path);
-               free(user_default_config_path);
-               free(user_lxc_path);
-               free(user_cgroup_pattern);
-               return values[i];
-       }
-
-       fin = fopen_cloexec(user_config_path, "r");
-       free(user_config_path);
-       if (fin) {
-               while (fgets(buf, 1024, fin)) {
-                       if (buf[0] == '#')
-                               continue;
-                       p = strstr(buf, option_name);
-                       if (!p)
-                               continue;
-                       /* see if there was just white space in front
-                        * of the option name
-                        */
-                       for (p2 = buf; p2 < p; p2++) {
-                               if (*p2 != ' ' && *p2 != '\t')
-                                       break;
-                       }
-                       if (p2 < p)
-                               continue;
-                       p = strchr(p, '=');
-                       if (!p)
-                               continue;
-                       /* see if there was just white space after
-                        * the option name
-                        */
-                       for (p2 += strlen(option_name); p2 < p; p2++) {
-                               if (*p2 != ' ' && *p2 != '\t')
-                                       break;
-                       }
-                       if (p2 < p)
-                               continue;
-                       p++;
-                       while (*p && (*p == ' ' || *p == '\t')) p++;
-                       if (!*p)
-                               continue;
-
-                       if (strcmp(option_name, "lxc.lxcpath") == 0) {
-                               free(user_lxc_path);
-                               user_lxc_path = copy_global_config_value(p);
-                               remove_trailing_slashes(user_lxc_path);
-                               values[i] = user_lxc_path;
-                               user_lxc_path = NULL;
-                               goto out;
-                       }
-
-                       values[i] = copy_global_config_value(p);
-                       goto out;
-               }
-       }
-       /* could not find value, use default */
-       if (strcmp(option_name, "lxc.lxcpath") == 0) {
-               remove_trailing_slashes(user_lxc_path);
-               values[i] = user_lxc_path;
-               user_lxc_path = NULL;
-       }
-       else if (strcmp(option_name, "lxc.default_config") == 0) {
-               values[i] = user_default_config_path;
-               user_default_config_path = NULL;
-       }
-       else if (strcmp(option_name, "lxc.cgroup.pattern") == 0) {
-               values[i] = user_cgroup_pattern;
-               user_cgroup_pattern = NULL;
-       }
-       else
-               values[i] = (*ptr)[1];
-
-       /* special case: if default value is NULL,
-        * and there is no config, don't view that
-        * as an error... */
-       if (!values[i])
-               errno = 0;
-
-out:
-       if (fin)
-               fclose(fin);
-
-       free(user_cgroup_pattern);
-       free(user_default_config_path);
-       free(user_lxc_path);
-
-       return values[i];
-}
-
 char *get_rundir()
 {
        char *rundir;
@@ -669,50 +451,6 @@ const char** lxc_va_arg_list_to_argv_const(va_list ap, size_t skip)
        return (const char**)lxc_va_arg_list_to_argv(ap, skip, 0);
 }
 
-FILE *fopen_cloexec(const char *path, const char *mode)
-{
-       int open_mode = 0;
-       int step = 0;
-       int fd;
-       int saved_errno = 0;
-       FILE *ret;
-
-       if (!strncmp(mode, "r+", 2)) {
-               open_mode = O_RDWR;
-               step = 2;
-       } else if (!strncmp(mode, "r", 1)) {
-               open_mode = O_RDONLY;
-               step = 1;
-       } else if (!strncmp(mode, "w+", 2)) {
-               open_mode = O_RDWR | O_TRUNC | O_CREAT;
-               step = 2;
-       } else if (!strncmp(mode, "w", 1)) {
-               open_mode = O_WRONLY | O_TRUNC | O_CREAT;
-               step = 1;
-       } else if (!strncmp(mode, "a+", 2)) {
-               open_mode = O_RDWR | O_CREAT | O_APPEND;
-               step = 2;
-       } else if (!strncmp(mode, "a", 1)) {
-               open_mode = O_WRONLY | O_CREAT | O_APPEND;
-               step = 1;
-       }
-       for (; mode[step]; step++)
-               if (mode[step] == 'x')
-                       open_mode |= O_EXCL;
-       open_mode |= O_CLOEXEC;
-
-       fd = open(path, open_mode, 0666);
-       if (fd < 0)
-               return NULL;
-
-       ret = fdopen(fd, mode);
-       saved_errno = errno;
-       if (!ret)
-               close(fd);
-       errno = saved_errno;
-       return ret;
-}
-
 extern struct lxc_popen_FILE *lxc_popen(const char *command)
 {
        struct lxc_popen_FILE *fp = NULL;
index cc189060439f57a94b3055cf744c3785cf3058fb..5dbc803734aa50c0a8c54f9ca71af14ccf6a095e 100644 (file)
 #include <unistd.h>
 
 #include "config.h"
+#include "initutils.h"
 
 /* returns 1 on success, 0 if there were any failures */
 extern int lxc_rmdir_onedev(char *path, const char *exclude);
-extern void lxc_setup_fs(void);
 extern int get_u16(unsigned short *val, const char *arg, int base);
 extern int mkdir_p(const char *dir, mode_t mode);
-extern void remove_trailing_slashes(char *p);
 extern char *get_rundir(void);
 
-extern const char *lxc_global_config_value(const char *option_name);
-
 /* Define getline() if missing from the C library */
 #ifndef HAVE_GETLINE
 #ifdef HAVE_FGETLN
@@ -148,10 +145,6 @@ static inline int signalfd(int fd, const sigset_t *mask, int flags)
 }
 #endif
 
-/* open a file with O_CLOEXEC */
-FILE *fopen_cloexec(const char *path, const char *mode);
-
-
 /* Struct to carry child pid from lxc_popen() to lxc_pclose().
  * Not an opaque struct to allow direct access to the underlying FILE *
  * (i.e., struct lxc_popen_FILE *file; fgets(buf, sizeof(buf), file->f))