From: Yoshihiro YUNOMAE <[email protected]>

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 <[email protected]>
Signed-off-by: Masami Hiramatsu <[email protected]>
---
 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);

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to