Messages in this thread Patch in this message | | | Subject | [PATCH trace-cmd V6 7/7] trace-cmd: Use pid instead of libvirt virt domain name | From | Masami Hiramatsu <> | Date | Tue, 26 May 2015 15:55:36 +0900 |
| |
From: Yoshihiro YUNOMAE <yoshihiro.yunomae.ez@hitachi.com>
Use pid instead of domain name if libvirt is not found. This also fix the trace fifo lookup routine to find it from /proc/<PID>/fd. With this change, we can use trace-cmd virt-server for directly running qemu virtual machines.
Signed-off-by: Yoshihiro YUNOMAE <yoshihiro.yunomae.ez@hitachi.com> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> --- trace-listen.c | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-)
diff --git a/trace-listen.c b/trace-listen.c index f6d53d2..f40b3a5 100644 --- a/trace-listen.c +++ b/trace-listen.c @@ -35,6 +35,7 @@ #include <fcntl.h> #include <signal.h> #include <errno.h> +#include <fnmatch.h> #include "trace-local.h" #include "trace-msg.h" @@ -396,20 +397,41 @@ static int open_udp(const char *node, const char *port, int *pid, #define TRACE_PATH_DOMAIN_CPU_O VIRT_DOMAIN_DIR "trace-path-cpu%d.out" #define TRACE_PATH_DOMAIN_CPU_I VIRT_DOMAIN_DIR "trace-path-cpu%d.in" +#define TRACE_PATH_PATTERN VIRT_DIR "*/trace-path-cpu%d.out" + static int open_virtio_serial_pipe(int *pid, int cpu, int pagesize, const char *domain, int virtpid) { + char path[PATH_MAX]; char buf[PATH_MAX]; - int fd; - - snprintf(buf, PATH_MAX, TRACE_PATH_DOMAIN_CPU_O, domain, cpu); - fd = open(buf, O_RDONLY | O_NONBLOCK); - if (fd < 0) { - warning("open %s", buf); - return fd; + int fd = -ENOENT; + DIR *dir; + struct dirent *ent; + struct stat st; + + snprintf(path, PATH_MAX, "/proc/%d/fd", virtpid); + dir = opendir(path); + if (!dir) + return -errno; + while ((ent = readdir(dir)) != NULL) { + snprintf(path, PATH_MAX, "/proc/%d/fd/%s", + virtpid, ent->d_name); + if (readlink(path, buf, PATH_MAX) < 0) + continue; + snprintf(path, PATH_MAX, TRACE_PATH_PATTERN, cpu); + /* Find the pipe which matchs pattern */ + if ((fnmatch(path, buf, FNM_PATHNAME) == 0) && + (stat(buf, &st) == 0) && (S_ISFIFO(st.st_mode))) { + fd = open(buf, O_RDONLY | O_NONBLOCK); + break; + } } + closedir(dir); - fork_virt_reader(fd, pid, cpu, pagesize, domain, virtpid); + if (fd < 0) + warning("open %s: %d", buf, fd); + else + fork_virt_reader(fd, pid, cpu, pagesize, domain, virtpid); return fd; } @@ -762,6 +784,7 @@ static int do_fork(int cfd) return 0; } +/* Get client (VM) pid from unix domain socket */ static int get_virtpid(int cfd) { struct ucred cr; @@ -790,11 +813,8 @@ static char *get_guest_domain_from_pid(int pid) int fd; dir = opendir(LIBVIRT_DOMAIN_PATH); - if (!dir) { - if (errno == ENOENT) - warning("Only support for using libvirt"); + if (!dir) return NULL; - } for (dirent = readdir(dir); dirent != NULL; dirent = readdir(dir)) { snprintf(file_name, NAME_MAX, LIBVIRT_DOMAIN_PATH"%s", @@ -837,7 +857,8 @@ static int do_connection(int cfd, struct sockaddr *peer_addr, domain = get_guest_domain_from_pid(virtpid); if (!domain) - return -1; + if (asprintf(&domain, "%d", virtpid) < 0) + return -ENOMEM; } ret = do_fork(cfd);
| |