]>
Commit | Line | Data |
---|---|---|
cc73685d | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
e9df7e1a | 2 | |
d38dd64a CB |
3 | #ifndef _GNU_SOURCE |
4 | #define _GNU_SOURCE 1 | |
5 | #endif | |
e9df7e1a CB |
6 | #include <grp.h> |
7 | #include <sched.h> | |
d38dd64a | 8 | #include <stdint.h> |
e9df7e1a CB |
9 | #include <stdio.h> |
10 | #include <stdlib.h> | |
e9df7e1a | 11 | #include <string.h> |
e9df7e1a | 12 | #include <sys/mount.h> |
d38dd64a CB |
13 | #include <sys/types.h> |
14 | #include <unistd.h> | |
e9df7e1a | 15 | |
d38dd64a | 16 | #include "config.h" |
e9df7e1a | 17 | #include "log.h" |
28d832c4 CB |
18 | #include "rsync.h" |
19 | #include "storage.h" | |
e8f764b6 | 20 | #include "syscall_wrappers.h" |
e9df7e1a CB |
21 | #include "utils.h" |
22 | ||
10bc1861 | 23 | lxc_log_define(rsync, lxc); |
e9df7e1a | 24 | |
17a367d8 | 25 | int lxc_storage_rsync_exec_wrapper(void *data) |
301faec2 CB |
26 | { |
27 | struct rsync_data *arg = data; | |
28 | return lxc_rsync(arg); | |
29 | } | |
30 | ||
17a367d8 CB |
31 | int lxc_rsync_exec_wrapper(void *data) |
32 | { | |
17a367d8 CB |
33 | struct rsync_data_char *args = data; |
34 | ||
464c4611 | 35 | if (!lxc_switch_uid_gid(0, 0)) |
17a367d8 CB |
36 | return -1; |
37 | ||
8af07f82 | 38 | if (!lxc_setgroups(0, NULL)) |
17a367d8 CB |
39 | return -1; |
40 | ||
41 | return lxc_rsync_exec(args->src, args->dest); | |
42 | } | |
43 | ||
301faec2 CB |
44 | int lxc_rsync_exec(const char *src, const char *dest) |
45 | { | |
46 | int ret; | |
47 | size_t l; | |
48 | char *s; | |
49 | ||
50 | l = strlen(src) + 2; | |
51 | s = malloc(l); | |
52 | if (!s) | |
53 | return -1; | |
54 | ||
55 | ret = snprintf(s, l, "%s", src); | |
55d83a7c C |
56 | if (ret < 0 || (size_t)ret >= l) { |
57 | free(s); | |
301faec2 | 58 | return -1; |
55d83a7c | 59 | } |
301faec2 CB |
60 | |
61 | s[l - 2] = '/'; | |
62 | s[l - 1] = '\0'; | |
63 | ||
64 | execlp("rsync", "rsync", "-aHXS", "--delete", s, dest, (char *)NULL); | |
5384511c | 65 | free(s); |
301faec2 CB |
66 | return -1; |
67 | } | |
68 | ||
69 | int lxc_rsync(struct rsync_data *data) | |
70 | { | |
71 | int ret; | |
41dc7155 | 72 | const char *dest, *src; |
17a367d8 | 73 | struct lxc_storage *orig = data->orig, *new = data->new; |
301faec2 CB |
74 | |
75 | ret = unshare(CLONE_NEWNS); | |
76 | if (ret < 0) { | |
77 | SYSERROR("Failed to unshare CLONE_NEWNS"); | |
78 | return -1; | |
79 | } | |
80 | ||
81 | ret = detect_shared_rootfs(); | |
82 | if (ret) { | |
83 | ret = mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL); | |
84 | if (ret < 0) | |
85 | SYSERROR("Failed to make \"/\" a slave mount"); | |
86 | } | |
87 | ||
88 | ret = orig->ops->mount(orig); | |
89 | if (ret < 0) { | |
90 | ERROR("Failed mounting \"%s\" on \"%s\"", orig->src, orig->dest); | |
91 | return -1; | |
92 | } | |
93 | ||
94 | ret = new->ops->mount(new); | |
95 | if (ret < 0) { | |
96 | ERROR("Failed mounting \"%s\" onto \"%s\"", new->src, new->dest); | |
97 | return -1; | |
98 | } | |
99 | ||
464c4611 | 100 | if (!lxc_switch_uid_gid(0, 0)) |
301faec2 | 101 | return -1; |
17a367d8 | 102 | |
8af07f82 | 103 | if (!lxc_setgroups(0, NULL)) |
301faec2 CB |
104 | return -1; |
105 | ||
106 | src = lxc_storage_get_path(orig->dest, orig->type); | |
107 | dest = lxc_storage_get_path(new->dest, new->type); | |
108 | ||
109 | ret = lxc_rsync_exec(src, dest); | |
110 | if (ret < 0) { | |
111 | ERROR("Failed to rsync from \"%s\" into \"%s\"", src, dest); | |
112 | return -1; | |
113 | } | |
114 | ||
115 | return 0; | |
116 | } |