diff --git a/include/proc_parse.h b/include/proc_parse.h index 3794d7c09..9906c2c12 100644 --- a/include/proc_parse.h +++ b/include/proc_parse.h @@ -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); diff --git a/mount.c b/mount.c index 01aaecff5..24f2ca84e 100644 --- a/mount.c +++ b/mount.c @@ -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; } diff --git a/proc_parse.c b/proc_parse.c index 5ebeaa574..07eea90c9 100644 --- a/proc_parse.c +++ b/proc_parse.c @@ -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; }