extern char *dir_new_path(char *src, const char *oldname, const char *name,
const char *oldpath, const char *lxcpath);
+int lxc_rsync_delta(struct rsync_data_char *data)
+{
+ int ret;
+
+ ret = lxc_switch_uid_gid(0, 0);
+ if (ret < 0)
+ return -1;
+
+ ret = lxc_setgroups(0, NULL);
+ if (ret < 0)
+ return -1;
+
+ ret = lxc_rsync_exec(data->src, data->dest);
+ if (ret < 0) {
+ ERROR("Failed to rsync from \"%s\" into \"%s\"", data->src,
+ data->dest);
+ return -1;
+ }
+
+ return 0;
+}
+
+int lxc_rsync_delta_wrapper(void *data)
+{
+ struct rsync_data_char *arg = data;
+ return lxc_rsync_delta(arg);
+}
+
int aufs_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
const char *oldname, const char *cname, const char *oldpath,
const char *lxcpath, int snap, uint64_t newsize,
struct lxc_conf *conf)
{
+ char cmd_output[MAXPATHLEN];
+
if (!snap) {
ERROR("aufs is only for snapshot clones");
return -22;
rdata.src = odelta;
rdata.dest = ndelta;
if (am_unpriv())
- ret = userns_exec_1(conf, rsync_delta_wrapper, &rdata,
- "rsync_delta_wrapper");
+ ret = userns_exec_1(conf, lxc_rsync_delta_wrapper,
+ &rdata, "lxc_rsync_delta_wrapper");
else
- ret = rsync_delta(&rdata);
+ ret = run_command(cmd_output, sizeof(cmd_output),
+ lxc_rsync_delta_wrapper,
+ (void *)&rdata);
if (ret) {
free(osrc);
free(ndelta);
lxc_log_define(rsync, 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", "-aHXS", "--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 lxc_storage *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);
-}
-
-/* new helpers */
int lxc_rsync_exec_wrapper(void *data)
{
struct rsync_data *arg = data;