Commit 420325dc authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

restore: add an option for changing a root file system (v2)

The option is -r|--pivot-root and an argument is a path to new root.
A root task will make pivot_root. LXC CT does that, so we need that
for restoring.

v2: s/pivot-root/root/
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 3cb5969b
...@@ -59,7 +59,7 @@ int main(int argc, char *argv[]) ...@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
int log_inited = 0; int log_inited = 0;
int log_level = 0; int log_level = 0;
static const char short_opts[] = "dsf:t:hcD:o:n:vxV"; static const char short_opts[] = "dsf:t:hcD:o:n:vxVr:";
BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE); BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE);
...@@ -79,6 +79,7 @@ int main(int argc, char *argv[]) ...@@ -79,6 +79,7 @@ int main(int argc, char *argv[])
{ "images-dir", required_argument, 0, 'D' }, { "images-dir", required_argument, 0, 'D' },
{ "log-file", required_argument, 0, 'o' }, { "log-file", required_argument, 0, 'o' },
{ "namespaces", required_argument, 0, 'n' }, { "namespaces", required_argument, 0, 'n' },
{ "root", required_argument, 0, 'r' },
{ "ext-unix-sk", no_argument, 0, 'x' }, { "ext-unix-sk", no_argument, 0, 'x' },
{ "help", no_argument, 0, 'h' }, { "help", no_argument, 0, 'h' },
{ SK_EST_PARAM, no_argument, 0, 42 }, { SK_EST_PARAM, no_argument, 0, 42 },
...@@ -108,6 +109,9 @@ int main(int argc, char *argv[]) ...@@ -108,6 +109,9 @@ int main(int argc, char *argv[])
case 'f': case 'f':
opts.show_dump_file = optarg; opts.show_dump_file = optarg;
break; break;
case 'r':
opts.root = optarg;
break;
case 'd': case 'd':
opts.restore_detach = true; opts.restore_detach = true;
break; break;
...@@ -245,6 +249,7 @@ usage: ...@@ -245,6 +249,7 @@ usage:
pr_msg(" supported: uts, ipc, pid\n"); pr_msg(" supported: uts, ipc, pid\n");
pr_msg(" -x|--ext-unix-sk allow external unix connections\n"); pr_msg(" -x|--ext-unix-sk allow external unix connections\n");
pr_msg(" --%s checkpoint/restore established TCP connections\n", SK_EST_PARAM); pr_msg(" --%s checkpoint/restore established TCP connections\n", SK_EST_PARAM);
pr_msg(" -r|--root [PATH] change the root filesystem (when run in mount namespace)\n");
pr_msg("\n* Logging:\n"); pr_msg("\n* Logging:\n");
pr_msg(" -o|--log-file [NAME] log file name (relative path is relative to --images-dir)\n"); pr_msg(" -o|--log-file [NAME] log file name (relative path is relative to --images-dir)\n");
......
...@@ -87,6 +87,7 @@ struct cr_options { ...@@ -87,6 +87,7 @@ struct cr_options {
unsigned int namespaces_flags; unsigned int namespaces_flags;
bool log_file_per_pid; bool log_file_per_pid;
char *output; char *output;
char *root;
}; };
extern struct cr_options opts; extern struct cr_options opts;
......
...@@ -15,4 +15,5 @@ struct cr_options; ...@@ -15,4 +15,5 @@ struct cr_options;
extern void show_mountpoints(int fd, struct cr_options *); extern void show_mountpoints(int fd, struct cr_options *);
int prepare_mnt_ns(int pid); int prepare_mnt_ns(int pid);
extern int pivot_root(const char *new_root, const char *put_old);
#endif /* MOUNT_H__ */ #endif /* MOUNT_H__ */
...@@ -378,6 +378,13 @@ static int do_umount_one(struct mount_info *mi) ...@@ -378,6 +378,13 @@ static int do_umount_one(struct mount_info *mi)
if (!mi->parent) if (!mi->parent)
return 0; return 0;
/*
* Don't umount the future root. It can be a mountpoint only,
* otherwise pivot_root() fails.
*/
if (opts.root && !strcmp(opts.root, mi->mountpoint))
return 0;
if (umount(mi->mountpoint)) { if (umount(mi->mountpoint)) {
pr_perror("Can't umount at %s", mi->mountpoint); pr_perror("Can't umount at %s", mi->mountpoint);
return -1; return -1;
...@@ -421,6 +428,33 @@ static int populate_mnt_ns(int ns_pid) ...@@ -421,6 +428,33 @@ static int populate_mnt_ns(int ns_pid)
pr_info("Populating mount namespace\n"); pr_info("Populating mount namespace\n");
if (opts.root) {
char put_root[PATH_MAX] = "crtools-put-root.XXXXXX";
if (chdir(opts.root)) {
pr_perror("chdir(%s) failed", opts.root);
return -1;
}
if (mkdtemp(put_root) == NULL) {
pr_perror("Can't create a temparary directory");
return -1;
}
if (pivot_root(".", put_root)) {
pr_perror("pivot_root(., %s) failed", put_root);
if (rmdir(put_root))
pr_perror("Can't remove the directory %s", put_root);
return -1;
}
if (umount2(put_root, MNT_DETACH)) {
pr_perror("Can't umount %s", put_root);
return -1;
}
if (rmdir(put_root)) {
pr_perror("Can't remove the directory %s", put_root);
return -1;
}
}
img = open_image_ro(CR_FD_MOUNTPOINTS, ns_pid); img = open_image_ro(CR_FD_MOUNTPOINTS, ns_pid);
if (img < 0) if (img < 0)
return -1; return -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment