]> git.itanic.dy.fi Git - scan-pagemap/commitdiff
parser: Remove unaccessible pids from the pidlist
authorTimo Kokkonen <kaapeli@itanic.dy.fi>
Thu, 26 Aug 2010 18:43:32 +0000 (21:43 +0300)
committerTimo Kokkonen <kaapeli@itanic.dy.fi>
Thu, 26 Aug 2010 18:43:32 +0000 (21:43 +0300)
If scan-pagemap is run without root priviledges and --shared-mappings
option is used, pids that are inaccessible to the user need to be
removed from the list of interesting pids. Otherwise
dunp_process_maps() will not print any pages for the given processes,
as it will try to count pages that are shared with all interesting
pids. If any pids from the list are inaccessible to the user, then
none of the pages are shared with these inaccessible pids. Therefore,
the inaccessible pids must be removed from the list altogether.

Since list entries are being removed from the list, all
list_for_each_entry will be need to be replaced with the _safe
variant.

Signed-off-by: Timo Kokkonen <kaapeli@itanic.dy.fi>
parse.c

diff --git a/parse.c b/parse.c
index a7b73cd2ab10e99b9b4155e83ea694dd4e278e7e..827264b8fb315e5a5a631a72759b517be9895f8c 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -245,6 +245,7 @@ static int read_pageframe(int pid, int tid, struct pageframe *pageframe,
 {
        struct maps *maps;
        struct process *process;
+       struct pidlist *pidl, *n;
        FILE *file;
        char path[512];
 
@@ -296,6 +297,17 @@ static int read_pageframe(int pid, int tid, struct pageframe *pageframe,
 free:
        free(process);
 
+       /*
+        * Remove the pid from the list. It is no longer an
+        * interesting pid, since we can't access its data
+        */
+       list_for_each_entry_safe(pidl, n, &opts->pidlist, list) {
+               if (pidl->pid == pid) {
+                       list_del(&pidl->list);
+                       break;
+               }
+       }
+
        return 0;
 }
 
@@ -330,13 +342,13 @@ static int read_pageframe_with_threads(int pid,
 int scan_all_pids(struct pageframe *pf, struct process *process_list,
                struct parse_opts *opts)
 {
-       struct pidlist *pidlist;
+       struct pidlist *pidlist, *n;
        DIR *dir = NULL;
        int pid;
        int count = 0;
 
        if (is_parse_option(opts, PARSE_PID)) {
-               list_for_each_entry(pidlist, &opts->pidlist, list) {
+               list_for_each_entry_safe(pidlist, n, &opts->pidlist, list) {
                        count += read_pageframe_with_threads(pidlist->pid, pf,
                                                        process_list, opts);
                }