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 <christian.brauner@mailbox.org>
This commit is contained in:
Christian Brauner 2015-12-18 00:24:32 +01:00
parent 93d4475ec2
commit cd0f1eebe5
6 changed files with 193 additions and 112 deletions

View File

@ -9,6 +9,7 @@ noinst_HEADERS = \
bdev/bdev.h \
bdev/lxcbtrfs.h \
bdev/lxcoverlay.h \
bdev/lxcrsync.h \
caps.h \
cgroup.h \
conf.h \

View File

@ -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);

View File

@ -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

View File

@ -37,6 +37,7 @@
#include "bdev.h"
#include "log.h"
#include "lxcbtrfs.h"
#include "lxcrsync.h"
#include "utils.h"
lxc_log_define(btrfs, lxc);

143
src/lxc/bdev/lxcrsync.c Normal file
View File

@ -0,0 +1,143 @@
/*
* 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
*/
#define _GNU_SOURCE
#include <grp.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mount.h>
#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);
}

46
src/lxc/bdev/lxcrsync.h Normal file
View File

@ -0,0 +1,46 @@
/*
* 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_RSYNC_H
#define __LXC_RSYNC_H
#define _GNU_SOURCE
#include <stdio.h>
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