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 @@
#include "compiler.h"
#include "types.h"
#include "eventfd.h"
#include "proc_parse.h"
#include "crtools.h"
#include "image.h"
#include "util.h"
......@@ -60,44 +60,36 @@ out:
pr_img_tail(CR_FD_EVENTFD);
}
static int dump_one_eventfd(int lfd, u32 id, const struct fd_parms *p)
{
int image_fd = fdset_fd(glob_fdset, CR_FD_EVENTFD);
struct eventfd_file_entry efe;
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;
}
struct eventfd_dump_arg {
u32 id;
const struct fd_parms *p;
bool dumped;
};
ret = read(fdinfo, buf, sizeof(buf));
close(fdinfo);
static int dump_eventfd_entry(union fdinfo_entries *e, void *arg)
{
struct eventfd_dump_arg *da = arg;
struct eventfd_file_entry *efe = &e->efd;
if (ret <= 0) {
pr_perror("Reading eventfd from %d (%d) failed", p->fd, lfd);
if (da->dumped) {
pr_err("Several counters in a file?\n");
return -1;
}
pos = strstr(buf, "eventfd-count:");
if (!pos || !sscanf(pos, "eventfd-count: %lx", &efe.counter)) {
pr_err("Counter value is not found for %d (%d)\n", p->fd, lfd);
return -1;
}
da->dumped = true;
efe->id = da->id;
efe->flags = da->p->flags;
efe->fown = da->p->fown;
pr_info_eventfd("Dumping ", &efe);
if (write_img(image_fd, &efe))
return -1;
pr_info_eventfd("Dumping ", efe);
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 = {
......
......@@ -15,7 +15,7 @@
#include "compiler.h"
#include "types.h"
#include "eventpoll.h"
#include "proc_parse.h"
#include "crtools.h"
#include "image.h"
#include "util.h"
......@@ -92,59 +92,28 @@ out:
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)
{
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_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.flags = p->flags;
e.fown = p->fown;
e.id = id;
e.flags = p->flags;
e.fown = p->fown;
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 0;
parsing_err:
pr_err("Parsing error %d (%d)", p->fd, lfd);
return -1;
return parse_fdinfo(lfd, FDINFO_EVENTPOLL, dump_eventpoll_entry, &id);
}
static const struct fdtype_ops eventpoll_ops = {
......
......@@ -3,7 +3,7 @@
#include <sys/types.h>
#include "types.h"
#include "image.h"
#include "list.h"
#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);
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 *);
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__ */
......@@ -675,3 +675,59 @@ err:
}
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