mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-23 10:16:41 +00:00
proc_parse: add helper to resolve sdev from fd
New get_sdev_from_fd helper first gets mnt_id from fd using fdinfo and then converts mnt_id to sdev using mountinfo. By default mnt_id to sdev conversion only works for mounts in mntinfo. If parse_mountinfo argument is true, will also parse current process mountinfo when looking for mount sdev, this should be used only with temporary mounts just created by criu in current mntns. v3: add argument to parse self mountinfo for auxiliary mounts Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
This commit is contained in:
parent
15c42696cf
commit
bbf5f642de
2 changed files with 54 additions and 0 deletions
|
|
@ -140,6 +140,7 @@ extern void clean_cr_time_mounts(void);
|
|||
|
||||
extern bool add_skip_mount(const char *mountpoint);
|
||||
struct ns_id;
|
||||
extern int get_sdev_from_fd(int fd, unsigned int *sdev, bool parse_mountinfo);
|
||||
extern struct mount_info *parse_mountinfo(pid_t pid, struct ns_id *nsid, bool for_dump);
|
||||
|
||||
extern int check_mnt_id(void);
|
||||
|
|
|
|||
|
|
@ -1527,6 +1527,59 @@ out:
|
|||
return exit_code;
|
||||
}
|
||||
|
||||
static int get_mountinfo_sdev_from_mntid(int mnt_id, unsigned int *sdev)
|
||||
{
|
||||
int exit_code = -1;
|
||||
FILE *f;
|
||||
|
||||
f = fopen_proc(PROC_SELF, "mountinfo");
|
||||
if (!f)
|
||||
return -1;
|
||||
|
||||
while (fgets(buf, BUF_SIZE, f)) {
|
||||
unsigned int kmaj, kmin;
|
||||
int id;
|
||||
|
||||
if (sscanf(buf, "%i %*i %u:%u", &id, &kmaj, &kmin) != 3) {
|
||||
pr_err("Failed to parse mountinfo line %s\n", buf);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (id == mnt_id) {
|
||||
*sdev = MKKDEV(kmaj, kmin);
|
||||
exit_code = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
err:
|
||||
fclose(f);
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
/* This works even on btrfs where stat does not show right sdev */
|
||||
int get_sdev_from_fd(int fd, unsigned int *sdev, bool parse_mountinfo)
|
||||
{
|
||||
struct mount_info *mi;
|
||||
int ret, mnt_id;
|
||||
|
||||
ret = get_fd_mntid(fd, &mnt_id);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
/* Simple case mnt_id is in dumped mntns */
|
||||
mi = lookup_mnt_id(mnt_id);
|
||||
if (mi) {
|
||||
*sdev = mi->s_dev_rt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!parse_mountinfo)
|
||||
return -1;
|
||||
|
||||
/* Complex case mnt_id is in mntns created by criu */
|
||||
return get_mountinfo_sdev_from_mntid(mnt_id, sdev);
|
||||
}
|
||||
|
||||
struct mount_info *parse_mountinfo(pid_t pid, struct ns_id *nsid, bool for_dump)
|
||||
{
|
||||
struct mount_info *list = NULL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue