Commit 5e593e9b authored by Pavel Emelyanov's avatar Pavel Emelyanov

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: 's avatarPavel Emelyanov <xemul@parallels.com>
parent f9d1f2b2
......@@ -91,9 +91,10 @@ struct proc_mountinfo {
unsigned int s_dev;
char root[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_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);
......
......@@ -15,38 +15,22 @@
#include "proc_parse.h"
static struct proc_mountinfo *mntinfo;
static int nr_mntinfo;
int open_mount(unsigned int s_dev)
{
static int last = 0;
int i;
struct proc_mountinfo *i;
again:
for (i = last; i < nr_mntinfo; i++) {
if (s_dev == mntinfo[i].s_dev) {
last = i;
return open(mntinfo[i].mountpoint, O_RDONLY);
}
}
if (last) {
last = 0;
goto again;
}
for (i = mntinfo; i != NULL; i = i->next)
if (s_dev == i->s_dev)
return open(i->mountpoint, O_RDONLY);
return -ENOENT;
}
int collect_mount_info(void)
{
nr_mntinfo = 64;
mntinfo = xmalloc(sizeof(*mntinfo) * nr_mntinfo);
if (!mntinfo)
return -1;
nr_mntinfo = parse_mountinfo(getpid(), mntinfo, nr_mntinfo);
if (nr_mntinfo < 1) {
mntinfo = parse_mountinfo(getpid());
if (!mntinfo) {
pr_err("Parsing mountinfo %d failed\n", getpid());
return -1;
}
......
......@@ -470,44 +470,49 @@ err_parse:
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];
int i = 0;
snprintf(str, sizeof(str), "/proc/%d/mountinfo", pid);
f = fopen(str, "r");
if (!f) {
pr_perror("Can't open %d mountinfo", pid);
return -1;
return NULL;
}
while (fgets(str, sizeof(str), f)) {
unsigned int kmaj, kmin, parent_mnt_id;
struct proc_mountinfo *new;
unsigned int kmaj, kmin;
int ret;
if ((i + 1) >= nr_elems) {
i = -ENOMEM;
goto out_close;
}
new = xmalloc(sizeof(*new));
if (!new)
goto err;
ret = sscanf(str, "%i %i %u:%u %63s %63s",
&mi[i].mnt_id, &parent_mnt_id,
&kmaj, &kmin, mi[i].root,
mi[i].mountpoint);
&new->mnt_id, &new->parent_mnt_id,
&kmaj, &kmin, new->root, new->mountpoint);
if (ret != 6) {
pr_err("Bad format in %d mountinfo\n", pid);
i = -1;
goto out_close;
goto err;
}
mi[i].s_dev = MKKDEV(kmaj, kmin);
i++;
new->s_dev = MKKDEV(kmaj, kmin);
new->next = list;
list = new;
}
out_close:
fclose(f);
out:
return i;
fclose(f);
return list;
err:
while (list) {
struct proc_mountinfo *next = list->next;
xfree(list);
list = next;
}
goto out;
}
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