mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 14:55:39 +00:00
proc: Sanitize mountinfo parsing
Make the proc_mountinfo obtaned after parse form a single linked list. That's much easier to handle and doesn't have an artificial limitation of 64 items... Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
@@ -91,9 +91,10 @@ struct proc_mountinfo {
|
|||||||
unsigned int s_dev;
|
unsigned int s_dev;
|
||||||
char root[64];
|
char root[64];
|
||||||
char mountpoint[64];
|
char mountpoint[64];
|
||||||
|
struct proc_mountinfo *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int parse_mountinfo(pid_t pid, struct proc_mountinfo *mi, int nr_elems);
|
extern struct proc_mountinfo *parse_mountinfo(pid_t pid);
|
||||||
extern int parse_pid_stat(pid_t pid, struct proc_pid_stat *s);
|
extern int parse_pid_stat(pid_t pid, struct proc_pid_stat *s);
|
||||||
extern int parse_pid_stat_small(pid_t pid, struct proc_pid_stat_small *s);
|
extern int parse_pid_stat_small(pid_t pid, struct proc_pid_stat_small *s);
|
||||||
extern int parse_smaps(pid_t pid, struct list_head *vma_area_list, bool use_map_files);
|
extern int parse_smaps(pid_t pid, struct list_head *vma_area_list, bool use_map_files);
|
||||||
|
28
mount.c
28
mount.c
@@ -15,38 +15,22 @@
|
|||||||
#include "proc_parse.h"
|
#include "proc_parse.h"
|
||||||
|
|
||||||
static struct proc_mountinfo *mntinfo;
|
static struct proc_mountinfo *mntinfo;
|
||||||
static int nr_mntinfo;
|
|
||||||
|
|
||||||
int open_mount(unsigned int s_dev)
|
int open_mount(unsigned int s_dev)
|
||||||
{
|
{
|
||||||
static int last = 0;
|
struct proc_mountinfo *i;
|
||||||
int i;
|
|
||||||
|
|
||||||
again:
|
for (i = mntinfo; i != NULL; i = i->next)
|
||||||
for (i = last; i < nr_mntinfo; i++) {
|
if (s_dev == i->s_dev)
|
||||||
if (s_dev == mntinfo[i].s_dev) {
|
return open(i->mountpoint, O_RDONLY);
|
||||||
last = i;
|
|
||||||
return open(mntinfo[i].mountpoint, O_RDONLY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last) {
|
|
||||||
last = 0;
|
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int collect_mount_info(void)
|
int collect_mount_info(void)
|
||||||
{
|
{
|
||||||
nr_mntinfo = 64;
|
mntinfo = parse_mountinfo(getpid());
|
||||||
mntinfo = xmalloc(sizeof(*mntinfo) * nr_mntinfo);
|
if (!mntinfo) {
|
||||||
if (!mntinfo)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
nr_mntinfo = parse_mountinfo(getpid(), mntinfo, nr_mntinfo);
|
|
||||||
if (nr_mntinfo < 1) {
|
|
||||||
pr_err("Parsing mountinfo %d failed\n", getpid());
|
pr_err("Parsing mountinfo %d failed\n", getpid());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
45
proc_parse.c
45
proc_parse.c
@@ -470,44 +470,49 @@ err_parse:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_mountinfo(pid_t pid, struct proc_mountinfo *mi, int nr_elems)
|
struct proc_mountinfo *parse_mountinfo(pid_t pid)
|
||||||
{
|
{
|
||||||
FILE *f = NULL;
|
struct proc_mountinfo *list = NULL;
|
||||||
|
FILE *f;
|
||||||
char str[256];
|
char str[256];
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
snprintf(str, sizeof(str), "/proc/%d/mountinfo", pid);
|
snprintf(str, sizeof(str), "/proc/%d/mountinfo", pid);
|
||||||
f = fopen(str, "r");
|
f = fopen(str, "r");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
pr_perror("Can't open %d mountinfo", pid);
|
pr_perror("Can't open %d mountinfo", pid);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fgets(str, sizeof(str), f)) {
|
while (fgets(str, sizeof(str), f)) {
|
||||||
unsigned int kmaj, kmin, parent_mnt_id;
|
struct proc_mountinfo *new;
|
||||||
|
unsigned int kmaj, kmin;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((i + 1) >= nr_elems) {
|
new = xmalloc(sizeof(*new));
|
||||||
i = -ENOMEM;
|
if (!new)
|
||||||
goto out_close;
|
goto err;
|
||||||
}
|
|
||||||
|
|
||||||
ret = sscanf(str, "%i %i %u:%u %63s %63s",
|
ret = sscanf(str, "%i %i %u:%u %63s %63s",
|
||||||
&mi[i].mnt_id, &parent_mnt_id,
|
&new->mnt_id, &new->parent_mnt_id,
|
||||||
&kmaj, &kmin, mi[i].root,
|
&kmaj, &kmin, new->root, new->mountpoint);
|
||||||
mi[i].mountpoint);
|
|
||||||
if (ret != 6) {
|
if (ret != 6) {
|
||||||
pr_err("Bad format in %d mountinfo\n", pid);
|
pr_err("Bad format in %d mountinfo\n", pid);
|
||||||
i = -1;
|
goto err;
|
||||||
goto out_close;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mi[i].s_dev = MKKDEV(kmaj, kmin);
|
new->s_dev = MKKDEV(kmaj, kmin);
|
||||||
i++;
|
new->next = list;
|
||||||
|
list = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
out_close:
|
|
||||||
fclose(f);
|
|
||||||
out:
|
out:
|
||||||
return i;
|
fclose(f);
|
||||||
|
return list;
|
||||||
|
|
||||||
|
err:
|
||||||
|
while (list) {
|
||||||
|
struct proc_mountinfo *next = list->next;
|
||||||
|
xfree(list);
|
||||||
|
list = next;
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user