From cd0f1eebe5786e7cc5ce8b8bbb0720f5ac0ccdad Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Fri, 18 Dec 2015 00:24:32 +0100 Subject: [PATCH] Split bdev into modules: lxcrsync The functions: - do_rsync(); - rsync_delta(); - rsync_delta_wrapper(); - rsync_rootfs(); - rsync_rootfs_wrapper(); and the structs - struct rsync_data; - struct rsync_data_char; move from bdev.{c,h} to lxcrsync.{c.h}. All functions previously declared as static become public. lxcrsync.{c,h} should allow for a reasonable amount of abstraction regarding our rsync functions. Some of the functions could easily be abstracted. Adapt Makefile.am to include lxcrsync.{c,h}. Signed-off-by: Christian Brauner --- src/lxc/Makefile.am | 1 + src/lxc/bdev/bdev.c | 109 +----------------------------- src/lxc/bdev/bdev.h | 5 -- src/lxc/bdev/lxcbtrfs.c | 1 + src/lxc/bdev/lxcrsync.c | 143 ++++++++++++++++++++++++++++++++++++++++ src/lxc/bdev/lxcrsync.h | 46 +++++++++++++ 6 files changed, 193 insertions(+), 112 deletions(-) create mode 100644 src/lxc/bdev/lxcrsync.c create mode 100644 src/lxc/bdev/lxcrsync.h diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am index 353de65403..f24e03d4ba 100644 --- a/src/lxc/Makefile.am +++ b/src/lxc/Makefile.am @@ -9,6 +9,7 @@ noinst_HEADERS = \ bdev/bdev.h \ bdev/lxcbtrfs.h \ bdev/lxcoverlay.h \ + bdev/lxcrsync.h \ caps.h \ cgroup.h \ conf.h \ diff --git a/src/lxc/bdev/bdev.c b/src/lxc/bdev/bdev.c index 4688d96cd4..bc6e14a250 100644 --- a/src/lxc/bdev/bdev.c +++ b/src/lxc/bdev/bdev.c @@ -53,9 +53,10 @@ #include "error.h" #include "log.h" #include "lxc.h" -#include "lxclock.h" #include "lxcbtrfs.h" +#include "lxclock.h" #include "lxcoverlay.h" +#include "lxcrsync.h" #include "namespace.h" #include "parse.h" #include "utils.h" @@ -77,32 +78,6 @@ lxc_log_define(bdev, lxc); -/* the bulk of this needs to become a common helper */ -int do_rsync(const char *src, const char *dest) -{ - // call out to rsync - pid_t pid; - char *s; - size_t l; - - pid = fork(); - if (pid < 0) - return -1; - if (pid > 0) - return wait_for_pid(pid); - - l = strlen(src) + 2; - s = malloc(l); - if (!s) - exit(1); - strcpy(s, src); - s[l-2] = '/'; - s[l-1] = '\0'; - - execlp("rsync", "rsync", "-aHX", "--delete", s, dest, (char *)NULL); - exit(1); -} - /* the bulk of this needs to become a common helper */ char *dir_new_path(char *src, const char *oldname, const char *name, const char *oldpath, const char *lxcpath) @@ -1641,32 +1616,6 @@ static const struct bdev_ops loop_ops = { .can_backup = true, }; -static int rsync_delta(struct rsync_data_char *data) -{ - if (setgid(0) < 0) { - ERROR("Failed to setgid to 0"); - return -1; - } - if (setgroups(0, NULL) < 0) - WARN("Failed to clear groups"); - if (setuid(0) < 0) { - ERROR("Failed to setuid to 0"); - return -1; - } - if (do_rsync(data->src, data->dest) < 0) { - ERROR("rsyncing %s to %s", data->src, data->dest); - return -1; - } - - return 0; -} - -static int rsync_delta_wrapper(void *data) -{ - struct rsync_data_char *arg = data; - return rsync_delta(arg); -} - /* overlay */ static const struct bdev_ops ovl_ops = { .detect = &ovl_detect, @@ -2365,60 +2314,6 @@ struct bdev *bdev_init(struct lxc_conf *conf, const char *src, const char *dst, return bdev; } -struct rsync_data { - struct bdev *orig; - struct bdev *new; -}; - -static int rsync_rootfs(struct rsync_data *data) -{ - struct bdev *orig = data->orig, - *new = data->new; - - if (unshare(CLONE_NEWNS) < 0) { - SYSERROR("unshare CLONE_NEWNS"); - return -1; - } - if (detect_shared_rootfs()) { - if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) { - SYSERROR("Failed to make / rslave"); - ERROR("Continuing..."); - } - } - - // If not a snapshot, copy the fs. - if (orig->ops->mount(orig) < 0) { - ERROR("failed mounting %s onto %s", orig->src, orig->dest); - return -1; - } - if (new->ops->mount(new) < 0) { - ERROR("failed mounting %s onto %s", new->src, new->dest); - return -1; - } - if (setgid(0) < 0) { - ERROR("Failed to setgid to 0"); - return -1; - } - if (setgroups(0, NULL) < 0) - WARN("Failed to clear groups"); - if (setuid(0) < 0) { - ERROR("Failed to setuid to 0"); - return -1; - } - if (do_rsync(orig->dest, new->dest) < 0) { - ERROR("rsyncing %s to %s", orig->src, new->src); - return -1; - } - - return 0; -} - -static int rsync_rootfs_wrapper(void *data) -{ - struct rsync_data *arg = data; - return rsync_rootfs(arg); -} - bool bdev_is_dir(struct lxc_conf *conf, const char *path) { struct bdev *orig = bdev_init(conf, path, NULL, NULL); diff --git a/src/lxc/bdev/bdev.h b/src/lxc/bdev/bdev.h index c11e6f87d4..233ff636c0 100644 --- a/src/lxc/bdev/bdev.h +++ b/src/lxc/bdev/bdev.h @@ -134,9 +134,4 @@ void detach_block_device(struct lxc_conf *conf); bool rootfs_is_blockdev(struct lxc_conf *conf); -struct rsync_data_char { - char *src; - char *dest; -}; - #endif // __LXC_BDEV_H diff --git a/src/lxc/bdev/lxcbtrfs.c b/src/lxc/bdev/lxcbtrfs.c index 229bf5f8e3..2db7c87cb7 100644 --- a/src/lxc/bdev/lxcbtrfs.c +++ b/src/lxc/bdev/lxcbtrfs.c @@ -37,6 +37,7 @@ #include "bdev.h" #include "log.h" #include "lxcbtrfs.h" +#include "lxcrsync.h" #include "utils.h" lxc_log_define(btrfs, lxc); diff --git a/src/lxc/bdev/lxcrsync.c b/src/lxc/bdev/lxcrsync.c new file mode 100644 index 0000000000..67fc702ae1 --- /dev/null +++ b/src/lxc/bdev/lxcrsync.c @@ -0,0 +1,143 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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 + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bdev.h" +#include "log.h" +#include "lxcbtrfs.h" +#include "lxcrsync.h" +#include "utils.h" + +lxc_log_define(lxcrsync, lxc); + +/* the bulk of this needs to become a common helper */ +int do_rsync(const char *src, const char *dest) +{ + // call out to rsync + pid_t pid; + char *s; + size_t l; + + pid = fork(); + if (pid < 0) + return -1; + if (pid > 0) + return wait_for_pid(pid); + + l = strlen(src) + 2; + s = malloc(l); + if (!s) + exit(1); + strcpy(s, src); + s[l-2] = '/'; + s[l-1] = '\0'; + + execlp("rsync", "rsync", "-aHX", "--delete", s, dest, (char *)NULL); + exit(1); +} + +int rsync_delta(struct rsync_data_char *data) +{ + if (setgid(0) < 0) { + ERROR("Failed to setgid to 0"); + return -1; + } + if (setgroups(0, NULL) < 0) + WARN("Failed to clear groups"); + if (setuid(0) < 0) { + ERROR("Failed to setuid to 0"); + return -1; + } + if (do_rsync(data->src, data->dest) < 0) { + ERROR("rsyncing %s to %s", data->src, data->dest); + return -1; + } + + return 0; +} + +int rsync_delta_wrapper(void *data) +{ + struct rsync_data_char *arg = data; + return rsync_delta(arg); +} + +int rsync_rootfs(struct rsync_data *data) +{ + struct bdev *orig = data->orig, + *new = data->new; + + if (unshare(CLONE_NEWNS) < 0) { + SYSERROR("unshare CLONE_NEWNS"); + return -1; + } + if (detect_shared_rootfs()) { + if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) { + SYSERROR("Failed to make / rslave"); + ERROR("Continuing..."); + } + } + + // If not a snapshot, copy the fs. + if (orig->ops->mount(orig) < 0) { + ERROR("failed mounting %s onto %s", orig->src, orig->dest); + return -1; + } + if (new->ops->mount(new) < 0) { + ERROR("failed mounting %s onto %s", new->src, new->dest); + return -1; + } + if (setgid(0) < 0) { + ERROR("Failed to setgid to 0"); + return -1; + } + if (setgroups(0, NULL) < 0) + WARN("Failed to clear groups"); + if (setuid(0) < 0) { + ERROR("Failed to setuid to 0"); + return -1; + } + if (do_rsync(orig->dest, new->dest) < 0) { + ERROR("rsyncing %s to %s", orig->src, new->src); + return -1; + } + + return 0; +} + +int rsync_rootfs_wrapper(void *data) +{ + struct rsync_data *arg = data; + return rsync_rootfs(arg); +} + diff --git a/src/lxc/bdev/lxcrsync.h b/src/lxc/bdev/lxcrsync.h new file mode 100644 index 0000000000..802a885018 --- /dev/null +++ b/src/lxc/bdev/lxcrsync.h @@ -0,0 +1,46 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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_RSYNC_H +#define __LXC_RSYNC_H + +#define _GNU_SOURCE +#include + +struct rsync_data { + struct bdev *orig; + struct bdev *new; +}; + +struct rsync_data_char { + char *src; + char *dest; +}; + +int do_rsync(const char *src, const char *dest); +int rsync_delta_wrapper(void *data); +int rsync_delta(struct rsync_data_char *data); +int rsync_rootfs(struct rsync_data *data); +int rsync_rootfs_wrapper(void *data); + +#endif // __LXC_RSYNC_H