Commit 0b9d1d97 authored by Pavel Emelyanov's avatar Pavel Emelyanov

event*: Move proc parsing stuff to proc_parse

And prepare it for inotify (oh my...)
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent decf115f
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include "compiler.h" #include "compiler.h"
#include "types.h" #include "types.h"
#include "eventfd.h" #include "eventfd.h"
#include "proc_parse.h"
#include "crtools.h" #include "crtools.h"
#include "image.h" #include "image.h"
#include "util.h" #include "util.h"
...@@ -60,44 +60,36 @@ out: ...@@ -60,44 +60,36 @@ out:
pr_img_tail(CR_FD_EVENTFD); pr_img_tail(CR_FD_EVENTFD);
} }
static int dump_one_eventfd(int lfd, u32 id, const struct fd_parms *p) struct eventfd_dump_arg {
{ u32 id;
int image_fd = fdset_fd(glob_fdset, CR_FD_EVENTFD); const struct fd_parms *p;
struct eventfd_file_entry efe; bool dumped;
char buf[64]; };
char *pos;
int ret, fdinfo;
efe.id = id;
efe.flags = p->flags;
efe.fown = p->fown;
snprintf(buf, sizeof(buf), "/proc/self/fdinfo/%d", lfd);
fdinfo = open(buf, O_RDONLY);
if (fdinfo < 0) {
pr_perror("Can't open %d (%d)", p->fd, lfd);
return -1;
}
ret = read(fdinfo, buf, sizeof(buf)); static int dump_eventfd_entry(union fdinfo_entries *e, void *arg)
close(fdinfo); {
struct eventfd_dump_arg *da = arg;
struct eventfd_file_entry *efe = &e->efd;
if (ret <= 0) { if (da->dumped) {
pr_perror("Reading eventfd from %d (%d) failed", p->fd, lfd); pr_err("Several counters in a file?\n");
return -1; return -1;
} }
pos = strstr(buf, "eventfd-count:"); da->dumped = true;
if (!pos || !sscanf(pos, "eventfd-count: %lx", &efe.counter)) { efe->id = da->id;
pr_err("Counter value is not found for %d (%d)\n", p->fd, lfd); efe->flags = da->p->flags;
return -1; efe->fown = da->p->fown;
}
pr_info_eventfd("Dumping ", &efe); pr_info_eventfd("Dumping ", efe);
if (write_img(image_fd, &efe))
return -1;
return 0; return write_img(fdset_fd(glob_fdset, CR_FD_EVENTFD), efe);
}
static int dump_one_eventfd(int lfd, u32 id, const struct fd_parms *p)
{
struct eventfd_dump_arg da = { .id = id, .p = p, };
return parse_fdinfo(lfd, FDINFO_EVENTFD, dump_eventfd_entry, &da);
} }
static const struct fdtype_ops eventfd_ops = { static const struct fdtype_ops eventfd_ops = {
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include "compiler.h" #include "compiler.h"
#include "types.h" #include "types.h"
#include "eventpoll.h" #include "eventpoll.h"
#include "proc_parse.h"
#include "crtools.h" #include "crtools.h"
#include "image.h" #include "image.h"
#include "util.h" #include "util.h"
...@@ -92,59 +92,28 @@ out: ...@@ -92,59 +92,28 @@ out:
pr_img_tail(CR_FD_EVENTPOLL); pr_img_tail(CR_FD_EVENTPOLL);
} }
static int dump_eventpoll_entry(union fdinfo_entries *e, void *arg)
{
struct eventpoll_tfd_entry *efd = &e->epl;
efd->id = *(u32 *)arg;
pr_info_eventpoll_tfd("Dumping: ", efd);
return write_img(fdset_fd(glob_fdset, CR_FD_EVENTPOLL_TFD), efd);
}
static int dump_one_eventpoll(int lfd, u32 id, const struct fd_parms *p) static int dump_one_eventpoll(int lfd, u32 id, const struct fd_parms *p)
{ {
int image_fd = fdset_fd(glob_fdset, CR_FD_EVENTPOLL);
int image_tfd = fdset_fd(glob_fdset, CR_FD_EVENTPOLL_TFD);
struct eventpoll_file_entry e; struct eventpoll_file_entry e;
struct eventpoll_tfd_entry efd;
char buf[PAGE_SIZE], *tok;
int ret, fdinfo;
snprintf(buf, sizeof(buf), "/proc/self/fdinfo/%d", lfd);
fdinfo = open(buf, O_RDONLY);
if (fdinfo < 0) {
pr_perror("Can't open %d (%d)", p->fd, lfd);
return -1;
}
ret = read(fdinfo, buf, sizeof(buf));
close(fdinfo);
if (ret <= 0) {
pr_perror("Reading eventpoll from %d (%d) failed", p->fd, lfd);
return -1;
}
e.id = id; e.id = id;
e.flags = p->flags; e.flags = p->flags;
e.fown = p->fown; e.fown = p->fown;
pr_info_eventpoll("Dumping ", &e); pr_info_eventpoll("Dumping ", &e);
if (write_img(image_fd, &e)) if (write_img(fdset_fd(glob_fdset, CR_FD_EVENTPOLL), &e))
return -1;
tok = strstr(buf, "tfd:");
if (!tok)
return 0;
tok = strtok(tok, "\n");
while (tok) {
efd.id = id;
if (sscanf(tok, "tfd: %8d events: %8x data: %16lx",
&efd.tfd, &efd.events, &efd.data) != 3)
goto parsing_err;
tok = strtok(NULL, "\n");
pr_info_eventpoll_tfd("Dumping: ", &efd);
if (write_img(image_tfd, &efd))
return -1; return -1;
}
return 0; return parse_fdinfo(lfd, FDINFO_EVENTPOLL, dump_eventpoll_entry, &id);
parsing_err:
pr_err("Parsing error %d (%d)", p->fd, lfd);
return -1;
} }
static const struct fdtype_ops eventpoll_ops = { static const struct fdtype_ops eventpoll_ops = {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <sys/types.h> #include <sys/types.h>
#include "types.h" #include "types.h"
#include "image.h"
#include "list.h" #include "list.h"
#define PROC_TASK_COMM_LEN 32 #define PROC_TASK_COMM_LEN 32
...@@ -117,4 +117,12 @@ extern int parse_pid_stat_small(pid_t pid, struct proc_pid_stat_small *s); ...@@ -117,4 +117,12 @@ 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);
extern int parse_pid_status(pid_t pid, struct proc_status_creds *); extern int parse_pid_status(pid_t pid, struct proc_status_creds *);
union fdinfo_entries {
struct eventfd_file_entry efd;
struct eventpoll_tfd_entry epl;
};
extern int parse_fdinfo(int fd, int type,
int (*cb)(union fdinfo_entries *e, void *arg), void *arg);
#endif /* PROC_PARSE_H__ */ #endif /* PROC_PARSE_H__ */
...@@ -675,3 +675,59 @@ err: ...@@ -675,3 +675,59 @@ err:
} }
goto out; goto out;
} }
#define fdinfo_field(str, field) !strncmp(str, field":", sizeof(field))
int parse_fdinfo(int fd, int type,
int (*cb)(union fdinfo_entries *e, void *arg), void *arg)
{
FILE *f;
char str[256];
sprintf(str, "/proc/self/fdinfo/%d", fd);
f = fopen(str, "r");
if (!f) {
pr_perror("Can't open fdinfo to parse");
return -1;
}
while (fgets(str, sizeof(str), f)) {
int ret;
union fdinfo_entries entry;
if (fdinfo_field(str, "pos") || fdinfo_field(str, "counter"))
continue;
if (fdinfo_field(str, "eventfd-count")) {
if (type != FDINFO_EVENTFD)
goto parse_err;
ret = sscanf(str, "eventfd-count: %lx",
&entry.efd.counter);
if (ret != 1)
goto parse_err;
ret = cb(&entry, arg);
if (ret)
return ret;
continue;
}
if (fdinfo_field(str, "tfd")) {
if (type != FDINFO_EVENTPOLL)
goto parse_err;
ret = sscanf(str, "tfd: %d events: %x data: %lx",
&entry.epl.tfd, &entry.epl.events, &entry.epl.data);
if (ret != 3)
goto parse_err;
ret = cb(&entry, arg);
if (ret)
return ret;
continue;
}
}
fclose(f);
return 0;
parse_err:
pr_perror("%s: error parsing [%s] for %d\n", __func__, str, type);
return -1;
}
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