struct rsync_data *arg = data;
return rsync_rootfs(arg);
}
+
+/* new helpers */
+int lxc_rsync_exec_wrapper(void *data)
+{
+ struct rsync_data *arg = data;
+ return lxc_rsync(arg);
+}
+
+int lxc_rsync_exec(const char *src, const char *dest)
+{
+ int ret;
+ size_t l;
+ char *s;
+
+ l = strlen(src) + 2;
+ s = malloc(l);
+ if (!s)
+ return -1;
+
+ ret = snprintf(s, l, "%s", src);
+ if (ret < 0 || (size_t)ret >= l)
+ return -1;
+
+ s[l - 2] = '/';
+ s[l - 1] = '\0';
+
+ execlp("rsync", "rsync", "-aHXS", "--delete", s, dest, (char *)NULL);
+ return -1;
+}
+
+int lxc_rsync(struct rsync_data *data)
+{
+ int ret;
+ struct bdev *orig = data->orig, *new = data->new;
+ char *dest, *src;
+
+ ret = unshare(CLONE_NEWNS);
+ if (ret < 0) {
+ SYSERROR("Failed to unshare CLONE_NEWNS");
+ return -1;
+ }
+
+ ret = detect_shared_rootfs();
+ if (ret) {
+ ret = mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL);
+ if (ret < 0)
+ SYSERROR("Failed to make \"/\" a slave mount");
+ }
+
+ ret = orig->ops->mount(orig);
+ if (ret < 0) {
+ ERROR("Failed mounting \"%s\" on \"%s\"", orig->src, orig->dest);
+ return -1;
+ }
+
+ ret = new->ops->mount(new);
+ if (ret < 0) {
+ ERROR("Failed mounting \"%s\" onto \"%s\"", new->src, new->dest);
+ return -1;
+ }
+
+ ret = lxc_switch_uid_gid(0, 0);
+ if (ret < 0)
+ return -1;
+ ret = lxc_setgroups(0, NULL);
+ if (ret < 0)
+ return -1;
+
+ src = lxc_storage_get_path(orig->dest, orig->type);
+ dest = lxc_storage_get_path(new->dest, new->type);
+
+ ret = lxc_rsync_exec(src, dest);
+ if (ret < 0) {
+ ERROR("Failed to rsync from \"%s\" into \"%s\"", src, dest);
+ return -1;
+ }
+
+ return 0;
+}