[CRIU] [PATCH v4 3/3] mount: Restore binfmt_misc content in case of missing mount
Kirill Tkhai
ktkhai at virtuozzo.com
Wed Jul 20 03:13:19 PDT 2016
In case of mount image is not containing binfmt_misc mountpoint,
scan image directory for binfmt_misc content file (binfmt-misc-xxx).
If a file is found, add temporary mountpoint to mount tree and
restore the content in ordinary way. Then, umount temporary mountpoint.
v4: New
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
criu/mount.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 59 insertions(+), 2 deletions(-)
diff --git a/criu/mount.c b/criu/mount.c
index d583429..8657c36 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -1379,6 +1379,39 @@ static int try_mount_binfmt_misc(struct ns_id *ns, unsigned int *s_dev)
return ret ? -1 : exit_code;
}
+static int find_binfmt_misc_img(unsigned int *s_dev)
+{
+ struct dirent *de;
+ int dfd, ret;
+ DIR *dir;
+
+ *s_dev = 0;
+ dfd = dup(get_service_fd(IMG_FD_OFF));
+ dir = fdopendir(dfd);
+ if (!dir) {
+ close(dfd);
+ pr_perror("Can't open img dir\n");
+ return -1;
+ }
+ rewinddir(dir);
+
+ errno = 0;
+ while ((de = readdir(dir)) != NULL) {
+ if (strncmp(de->d_name, "binfmt-misc-", 12) == 0) {
+ *s_dev = (unsigned int)strtoul(de->d_name + 12, NULL, 10);
+ break;
+ }
+ }
+ ret = errno;
+ if (ret)
+ pr_perror("Can't read dir\n");
+ else if (*s_dev)
+ pr_info("Found binfmt_misc img for dev=%u\n", *s_dev);
+ closedir(dir);
+
+ return ret ? -1 : (*s_dev != 0);
+}
+
static int binfmt_misc_virtual(struct mount_info *pm)
{
return kerndat_fs_virtualized(KERNDAT_FS_STAT_BINFMT_MISC, pm->s_dev);
@@ -2442,6 +2475,15 @@ static int do_new_mount(struct mount_info *mi)
if (tp->restore && tp->restore(mi))
return -1;
+ if (!mi->mnt_id) {
+ /* C-r time mountpoint, umount it */
+ if (umount(mi->mountpoint) < 0) {
+ pr_perror("Can't umount %s\n", mi->mountpoint);
+ return -1;
+ }
+ goto out;
+ }
+
if (remount_ro && mount(NULL, mi->mountpoint, tp->name,
MS_REMOUNT | MS_RDONLY, NULL)) {
pr_perror("Unable to apply mount options");
@@ -2461,7 +2503,7 @@ static int do_new_mount(struct mount_info *mi)
BUG_ON(mi->master_id);
if (restore_shared_options(mi, !mi->shared_id, mi->shared_id, 0))
return -1;
-
+out:
mi->mounted = true;
return 0;
@@ -3324,7 +3366,7 @@ static int populate_roots_yard(void)
static int populate_mnt_ns(void)
{
- struct mount_info *pms;
+ struct mount_info *pms, *mi;
struct ns_id *nsid;
struct mount_info *roots_mp = NULL;
int ret;
@@ -3343,6 +3385,21 @@ static int populate_mnt_ns(void)
if (!pms)
return -1;
+ for (mi = mntinfo; mi != NULL; mi = mi->next) {
+ if (strcmp(mi->fstype->name, "binfmt_misc") == 0)
+ break;
+ }
+
+ if (!mi) {
+ unsigned int s_dev;
+
+ ret = find_binfmt_misc_img(&s_dev);
+ if (ret > 0)
+ ret = add_cr_time_mount(pms, "binfmt_misc", BINFMT_MISC_HOME, s_dev);
+ if (ret < 0)
+ return -1;
+ }
+
if (resolve_shared_mounts(mntinfo, pms->master_id))
return -1;
More information about the CRIU
mailing list