Re: [PATCH V2 4/5] trace-cmd: Add virt-server mode for a virtualization environment

2013-10-22 Thread Yoshihiro YUNOMAE

(2013/10/18 11:32), Steven Rostedt wrote:

On Fri, 13 Sep 2013 11:06:37 +0900
Yoshihiro YUNOMAE  wrote:


  static int *create_all_readers(int cpus, const char *node, const char *port,
-  int pagesize, int fd)
+  const char *domain, int virtpid, int pagesize, 
int fd)
  {
char buf[BUFSIZ];
-   int *port_array;
+   int *port_array = NULL;
int *pid_array;
int start_port;
int udp_port;
int cpu;
int pid;

-   port_array = malloc_or_die(sizeof(int) * cpus);
+   if (node) {
+   port_array = malloc_or_die(sizeof(int) * cpus);
+   start_port = START_PORT_SEARCH;
+   }
pid_array = malloc_or_die(sizeof(int) * cpus);
memset(pid_array, 0, sizeof(int) * cpus);

-   start_port = START_PORT_SEARCH;
-
-   /* Now create a UDP port for each CPU */
+   /* Now create a reader for each CPU */
for (cpu = 0; cpu < cpus; cpu++) {
-   udp_port = open_udp(node, port, , cpu,
-   pagesize, start_port);
-   if (udp_port < 0)
-   goto out_free;
-   port_array[cpu] = udp_port;
+   if (node) {
+   udp_port = open_udp(node, port, , cpu,
+   pagesize, start_port);
+   if (udp_port < 0)
+   goto out_free;
+   port_array[cpu] = udp_port;
+   /*
+* due to some bugging finding ports,


s/due/Due/


Thanks.


+* force search after last port
+*/
+   start_port = udp_port + 1;
+   } else {
+   if (open_virtio_serial_pipe(, cpu, pagesize,
+   domain, virtpid) < 0)
+   goto out_free;
+   }
pid_array[cpu] = pid;
/*
 * Due to some bugging finding ports,


Hmm, it seems that you added the start_port = udp_port + 1 above, but
shouldn't you remove the one here?


Oh, you're right.
I'll delete it here.


@@ -482,7 +595,7 @@ static int *create_all_readers(int cpus, const char *node, 
const char *port,
return pid_array;

   out_free:
-   destroy_all_readers(cpus, pid_array, node, port);
+   destroy_all_readers(cpus, pid_array, node, port, domain, virtpid);
return NULL;
  }

@@ -524,7 +637,7 @@ static void stop_all_readers(int cpus, int *pid_array)
  }

  static void put_together_file(int cpus, int ofd, const char *node,
- const char *port)
+ const char *port, const char *domain, int virtpid)
  {
char **temp_files;
int cpu;
@@ -533,25 +646,31 @@ static void put_together_file(int cpus, int ofd, const 
char *node,
temp_files = malloc_or_die(sizeof(*temp_files) * cpus);

for (cpu = 0; cpu < cpus; cpu++)
-   temp_files[cpu] = get_temp_file(node, port, cpu);
+   temp_files[cpu] = get_temp_file(node, port, domain,
+   virtpid, cpu);

tracecmd_attach_cpu_data_fd(ofd, cpus, temp_files);
free(temp_files);
  }

-static void process_client(const char *node, const char *port, int fd)
+static void process_client(const char *node, const char *port,
+  const char *domain, int virtpid, int fd)
  {
int *pid_array;
int pagesize;
int cpus;
int ofd;

-   if (communicate_with_client(fd, , ) < 0)
-   return;
-
-   ofd = create_client_file(node, port);
+   if (node) {
+   if (communicate_with_client_nw(fd, , ) < 0)


I take it _nw is for "network". If so, please use "*_net" instead. "nw"
is pretty meaningless.

This applies for all functions.


OK, I'll rename all functions using _nw.

Thanks,
Yoshihiro YUNOMAE

--
Yoshihiro YUNOMAE
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: yoshihiro.yunomae...@hitachi.com


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


Re: [PATCH V2 4/5] trace-cmd: Add virt-server mode for a virtualization environment

2013-10-22 Thread Yoshihiro YUNOMAE

(2013/10/18 11:32), Steven Rostedt wrote:

On Fri, 13 Sep 2013 11:06:37 +0900
Yoshihiro YUNOMAE yoshihiro.yunomae...@hitachi.com wrote:


  static int *create_all_readers(int cpus, const char *node, const char *port,
-  int pagesize, int fd)
+  const char *domain, int virtpid, int pagesize, 
int fd)
  {
char buf[BUFSIZ];
-   int *port_array;
+   int *port_array = NULL;
int *pid_array;
int start_port;
int udp_port;
int cpu;
int pid;

-   port_array = malloc_or_die(sizeof(int) * cpus);
+   if (node) {
+   port_array = malloc_or_die(sizeof(int) * cpus);
+   start_port = START_PORT_SEARCH;
+   }
pid_array = malloc_or_die(sizeof(int) * cpus);
memset(pid_array, 0, sizeof(int) * cpus);

-   start_port = START_PORT_SEARCH;
-
-   /* Now create a UDP port for each CPU */
+   /* Now create a reader for each CPU */
for (cpu = 0; cpu  cpus; cpu++) {
-   udp_port = open_udp(node, port, pid, cpu,
-   pagesize, start_port);
-   if (udp_port  0)
-   goto out_free;
-   port_array[cpu] = udp_port;
+   if (node) {
+   udp_port = open_udp(node, port, pid, cpu,
+   pagesize, start_port);
+   if (udp_port  0)
+   goto out_free;
+   port_array[cpu] = udp_port;
+   /*
+* due to some bugging finding ports,


s/due/Due/


Thanks.


+* force search after last port
+*/
+   start_port = udp_port + 1;
+   } else {
+   if (open_virtio_serial_pipe(pid, cpu, pagesize,
+   domain, virtpid)  0)
+   goto out_free;
+   }
pid_array[cpu] = pid;
/*
 * Due to some bugging finding ports,


Hmm, it seems that you added the start_port = udp_port + 1 above, but
shouldn't you remove the one here?


Oh, you're right.
I'll delete it here.


@@ -482,7 +595,7 @@ static int *create_all_readers(int cpus, const char *node, 
const char *port,
return pid_array;

   out_free:
-   destroy_all_readers(cpus, pid_array, node, port);
+   destroy_all_readers(cpus, pid_array, node, port, domain, virtpid);
return NULL;
  }

@@ -524,7 +637,7 @@ static void stop_all_readers(int cpus, int *pid_array)
  }

  static void put_together_file(int cpus, int ofd, const char *node,
- const char *port)
+ const char *port, const char *domain, int virtpid)
  {
char **temp_files;
int cpu;
@@ -533,25 +646,31 @@ static void put_together_file(int cpus, int ofd, const 
char *node,
temp_files = malloc_or_die(sizeof(*temp_files) * cpus);

for (cpu = 0; cpu  cpus; cpu++)
-   temp_files[cpu] = get_temp_file(node, port, cpu);
+   temp_files[cpu] = get_temp_file(node, port, domain,
+   virtpid, cpu);

tracecmd_attach_cpu_data_fd(ofd, cpus, temp_files);
free(temp_files);
  }

-static void process_client(const char *node, const char *port, int fd)
+static void process_client(const char *node, const char *port,
+  const char *domain, int virtpid, int fd)
  {
int *pid_array;
int pagesize;
int cpus;
int ofd;

-   if (communicate_with_client(fd, cpus, pagesize)  0)
-   return;
-
-   ofd = create_client_file(node, port);
+   if (node) {
+   if (communicate_with_client_nw(fd, cpus, pagesize)  0)


I take it _nw is for network. If so, please use *_net instead. nw
is pretty meaningless.

This applies for all functions.


OK, I'll rename all functions using _nw.

Thanks,
Yoshihiro YUNOMAE

--
Yoshihiro YUNOMAE
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: yoshihiro.yunomae...@hitachi.com


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


Re: [PATCH V2 4/5] trace-cmd: Add virt-server mode for a virtualization environment

2013-10-17 Thread Steven Rostedt
On Fri, 13 Sep 2013 11:06:37 +0900
Yoshihiro YUNOMAE  wrote:

>  static int *create_all_readers(int cpus, const char *node, const char *port,
> -int pagesize, int fd)
> +const char *domain, int virtpid, int pagesize, 
> int fd)
>  {
>   char buf[BUFSIZ];
> - int *port_array;
> + int *port_array = NULL;
>   int *pid_array;
>   int start_port;
>   int udp_port;
>   int cpu;
>   int pid;
>  
> - port_array = malloc_or_die(sizeof(int) * cpus);
> + if (node) {
> + port_array = malloc_or_die(sizeof(int) * cpus);
> + start_port = START_PORT_SEARCH;
> + }
>   pid_array = malloc_or_die(sizeof(int) * cpus);
>   memset(pid_array, 0, sizeof(int) * cpus);
>  
> - start_port = START_PORT_SEARCH;
> -
> - /* Now create a UDP port for each CPU */
> + /* Now create a reader for each CPU */
>   for (cpu = 0; cpu < cpus; cpu++) {
> - udp_port = open_udp(node, port, , cpu,
> - pagesize, start_port);
> - if (udp_port < 0)
> - goto out_free;
> - port_array[cpu] = udp_port;
> + if (node) {
> + udp_port = open_udp(node, port, , cpu,
> + pagesize, start_port);
> + if (udp_port < 0)
> + goto out_free;
> + port_array[cpu] = udp_port;
> + /*
> +  * due to some bugging finding ports,

s/due/Due/

> +  * force search after last port
> +  */
> + start_port = udp_port + 1;
> + } else {
> + if (open_virtio_serial_pipe(, cpu, pagesize,
> + domain, virtpid) < 0)
> + goto out_free;
> + }
>   pid_array[cpu] = pid;
>   /*
>* Due to some bugging finding ports,

Hmm, it seems that you added the start_port = udp_port + 1 above, but
shouldn't you remove the one here?

> @@ -482,7 +595,7 @@ static int *create_all_readers(int cpus, const char 
> *node, const char *port,
>   return pid_array;
>  
>   out_free:
> - destroy_all_readers(cpus, pid_array, node, port);
> + destroy_all_readers(cpus, pid_array, node, port, domain, virtpid);
>   return NULL;
>  }
>  
> @@ -524,7 +637,7 @@ static void stop_all_readers(int cpus, int *pid_array)
>  }
>  
>  static void put_together_file(int cpus, int ofd, const char *node,
> -   const char *port)
> +   const char *port, const char *domain, int virtpid)
>  {
>   char **temp_files;
>   int cpu;
> @@ -533,25 +646,31 @@ static void put_together_file(int cpus, int ofd, const 
> char *node,
>   temp_files = malloc_or_die(sizeof(*temp_files) * cpus);
>  
>   for (cpu = 0; cpu < cpus; cpu++)
> - temp_files[cpu] = get_temp_file(node, port, cpu);
> + temp_files[cpu] = get_temp_file(node, port, domain,
> + virtpid, cpu);
>  
>   tracecmd_attach_cpu_data_fd(ofd, cpus, temp_files);
>   free(temp_files);
>  }
>  
> -static void process_client(const char *node, const char *port, int fd)
> +static void process_client(const char *node, const char *port,
> +const char *domain, int virtpid, int fd)
>  {
>   int *pid_array;
>   int pagesize;
>   int cpus;
>   int ofd;
>  
> - if (communicate_with_client(fd, , ) < 0)
> - return;
> -
> - ofd = create_client_file(node, port);
> + if (node) {
> + if (communicate_with_client_nw(fd, , ) < 0)

I take it _nw is for "network". If so, please use "*_net" instead. "nw"
is pretty meaningless.

This applies for all functions.

-- Steve

> + return;
> + } else {
> + if (communicate_with_client_virt(fd, domain, , ) 
> < 0)
> + return;
> + }
>  
> - pid_array = create_all_readers(cpus, node, port, pagesize, fd);
> + ofd = create_client_file(node, port, domain, virtpid);
> + pid_array = create_all_readers(cpus, node, port, domain, virtpid, 
> pagesize, fd);
>   if (!pid_array)
>   return;
>  
> @@ -570,9 +689,22 @@ static void process_client(const char *node, const char 
> *port, int fd)
>   /* wait a little to have the readers clean up */
>   sleep(1);
>  
> - put_together_file(cpus, ofd, node, port);
> + put_together_file(cpus, ofd, node, port, domain, virtpid);
>  
> - destroy_all_readers(cpus, pid_array, node, port);
> + destroy_all_readers(cpus, pid_array, node, port, domain, virtpid);
> +}
> +
> +static void process_client_nw(const char *node, const char *port, int fd)
> +{
> + process_client(node, port, NULL, 0, fd);
> +}
> +
> 

Re: [PATCH V2 4/5] trace-cmd: Add virt-server mode for a virtualization environment

2013-10-17 Thread Steven Rostedt
On Fri, 13 Sep 2013 11:06:37 +0900
Yoshihiro YUNOMAE yoshihiro.yunomae...@hitachi.com wrote:

  static int *create_all_readers(int cpus, const char *node, const char *port,
 -int pagesize, int fd)
 +const char *domain, int virtpid, int pagesize, 
 int fd)
  {
   char buf[BUFSIZ];
 - int *port_array;
 + int *port_array = NULL;
   int *pid_array;
   int start_port;
   int udp_port;
   int cpu;
   int pid;
  
 - port_array = malloc_or_die(sizeof(int) * cpus);
 + if (node) {
 + port_array = malloc_or_die(sizeof(int) * cpus);
 + start_port = START_PORT_SEARCH;
 + }
   pid_array = malloc_or_die(sizeof(int) * cpus);
   memset(pid_array, 0, sizeof(int) * cpus);
  
 - start_port = START_PORT_SEARCH;
 -
 - /* Now create a UDP port for each CPU */
 + /* Now create a reader for each CPU */
   for (cpu = 0; cpu  cpus; cpu++) {
 - udp_port = open_udp(node, port, pid, cpu,
 - pagesize, start_port);
 - if (udp_port  0)
 - goto out_free;
 - port_array[cpu] = udp_port;
 + if (node) {
 + udp_port = open_udp(node, port, pid, cpu,
 + pagesize, start_port);
 + if (udp_port  0)
 + goto out_free;
 + port_array[cpu] = udp_port;
 + /*
 +  * due to some bugging finding ports,

s/due/Due/

 +  * force search after last port
 +  */
 + start_port = udp_port + 1;
 + } else {
 + if (open_virtio_serial_pipe(pid, cpu, pagesize,
 + domain, virtpid)  0)
 + goto out_free;
 + }
   pid_array[cpu] = pid;
   /*
* Due to some bugging finding ports,

Hmm, it seems that you added the start_port = udp_port + 1 above, but
shouldn't you remove the one here?

 @@ -482,7 +595,7 @@ static int *create_all_readers(int cpus, const char 
 *node, const char *port,
   return pid_array;
  
   out_free:
 - destroy_all_readers(cpus, pid_array, node, port);
 + destroy_all_readers(cpus, pid_array, node, port, domain, virtpid);
   return NULL;
  }
  
 @@ -524,7 +637,7 @@ static void stop_all_readers(int cpus, int *pid_array)
  }
  
  static void put_together_file(int cpus, int ofd, const char *node,
 -   const char *port)
 +   const char *port, const char *domain, int virtpid)
  {
   char **temp_files;
   int cpu;
 @@ -533,25 +646,31 @@ static void put_together_file(int cpus, int ofd, const 
 char *node,
   temp_files = malloc_or_die(sizeof(*temp_files) * cpus);
  
   for (cpu = 0; cpu  cpus; cpu++)
 - temp_files[cpu] = get_temp_file(node, port, cpu);
 + temp_files[cpu] = get_temp_file(node, port, domain,
 + virtpid, cpu);
  
   tracecmd_attach_cpu_data_fd(ofd, cpus, temp_files);
   free(temp_files);
  }
  
 -static void process_client(const char *node, const char *port, int fd)
 +static void process_client(const char *node, const char *port,
 +const char *domain, int virtpid, int fd)
  {
   int *pid_array;
   int pagesize;
   int cpus;
   int ofd;
  
 - if (communicate_with_client(fd, cpus, pagesize)  0)
 - return;
 -
 - ofd = create_client_file(node, port);
 + if (node) {
 + if (communicate_with_client_nw(fd, cpus, pagesize)  0)

I take it _nw is for network. If so, please use *_net instead. nw
is pretty meaningless.

This applies for all functions.

-- Steve

 + return;
 + } else {
 + if (communicate_with_client_virt(fd, domain, cpus, pagesize) 
  0)
 + return;
 + }
  
 - pid_array = create_all_readers(cpus, node, port, pagesize, fd);
 + ofd = create_client_file(node, port, domain, virtpid);
 + pid_array = create_all_readers(cpus, node, port, domain, virtpid, 
 pagesize, fd);
   if (!pid_array)
   return;
  
 @@ -570,9 +689,22 @@ static void process_client(const char *node, const char 
 *port, int fd)
   /* wait a little to have the readers clean up */
   sleep(1);
  
 - put_together_file(cpus, ofd, node, port);
 + put_together_file(cpus, ofd, node, port, domain, virtpid);
  
 - destroy_all_readers(cpus, pid_array, node, port);
 + destroy_all_readers(cpus, pid_array, node, port, domain, virtpid);
 +}
 +
 +static void process_client_nw(const char *node, const char *port, int fd)
 +{
 + process_client(node, port, NULL, 0, fd);
 +}
 +
 +static void process_client_virt(const char *domain, int virtpid, 

[PATCH V2 4/5] trace-cmd: Add virt-server mode for a virtualization environment

2013-09-12 Thread Yoshihiro YUNOMAE
Add the virt-server mode for a virtualization environment based on the listen
mode for networking. This mode works like client/server mode over TCP/UDP,
but it uses virtio-serial channel instead of IP network. Using networking for
collecting trace data of guests is generally high overhead caused by processing
of the network stack.

We use virtio-serial for collecting trace data of guests. virtio-serial is a
simple communication path between the guest and the host. Moreover,
since virtio-serial and ftrace can use splice(2), memory copying is not
occurred on the guests. Therefore, total overhead for collecting trace data
of the guests will be reduced. The implementation of clients will be shown
in another patch.

virt-server uses two kinds of virtio-serial I/Fs:
(1) agent-ctl-path(UNIX domain socket)
=> control path of an agent trace-cmd each guest
(2) trace-path-cpuX(named pipe)
=> trace data path each vcpu

Those I/Fs must be defined as below paths:
(1) /tmp/trace-cmd/virt/agent-ctl-path
(2) /tmp/trace-cmd/virt//trace-path-cpuX

If we run virt-server, agent-ctl-path I/F is automatically created because
virt-server operates as a server mode of UNIX domain socket. However,
trace-path-cpuX is not automatically created because we need to separate
trace data for each guests.

When the client uses virtio-serial, the client must notify the server of the
connection. This is because a virtio-serial I/F on the guest is a just character
device. In other words, the server cannot understand whether the client exists
or not even if the client opens the I/F. So, the server using virtio-serial
waits for the connection message MSG_TCONNECT from the client.
The server and the client operate as follows:

  
  wait for MSG_TCONNECT
  open virtio-serial I/F
  send MSG_TCONNECT
  receive MSG_TCONNECT <+
  send MSG_RCONNECT
+---> receive MSG_RCONNECT
  check "tracecmd-V2"
  send cpus,pagesize,option(MSG_TINIT)
  receive MSG_TINIT <---+
  print "cpus=XXX"
  print "pagesize=XXX"
  understand option
  send port_array
   +--MSG_RINIT-> receive MSG_RINIT
  understand port_array
  send meta data(MSG_SENDMETA)
  receive MSG_SENDMETA <+
  record meta data
 (snip)
  send a message to finish sending meta data
|   (MSG_FINMETA)
  receive MSG_FINMETA <-+
  read block
 --- start sending trace data on child processes ---

 --- When client finishes sending trace data ---
  send MSG_CLOSE
  receive MSG_CLOSE <---+
  close(socket fd)close(socket fd)


1. Run virt-server on a host before booting guests
   # trace-cmd virt-server

2. Make guest domain directory
   # mkdir -p /tmp/trace-cmd/virt/
   # chmod 710 /tmp/trace-cmd/virt/
   # chgrp qemu /tmp/trace-cmd/virt/

3. Make FIFO on the host
   # mkfifo /tmp/trace-cmd/virt//trace-path-cpu{0,1,...,X}.{in,out}

4. Set up of virtio-serial pipe of a guest on the host
   Add the following tags to domain XML files.
   # virsh edit 
   
  
  
   
   
  
  
   
   ... (cpu1, cpu2, ...)

5. Boot the guest
   # virsh start 

6. Check I/F of virtio-serial on the guest
   # ls /dev/virtio-ports
 ...
 agent-ctl-path
 ...
 trace-path-cpu0
 ...

Next, the user will run trace-cmd with record --virt options or other options
for virtualization on the guest.

This patch adds only minimum features of virt-server as follows:

 - virt-server subcommand
 - Create I/F directory(/tmp/trace-cmd/virt/)
 - Use named pipe I/Fs of virtio-serial for trace data paths
 - Use UNIX domain socket for connecting clients on guests
 - Use splice(2) for collecting trace data of guests


 - Use libvirt when we boot guests

Signed-off-by: Yoshihiro YUNOMAE 
---
 Documentation/trace-cmd-virt-server.1.txt |   89 ++
 trace-cmd.c   |3 
 trace-cmd.h   |2 
 trace-listen.c|  434 -
 trace-msg.c   |  105 +++
 trace-recorder.c  |   54 +++-
 trace-usage.c |   10 +
 7 files changed, 602 insertions(+), 95 deletions(-)
 create mode 100644 Documentation/trace-cmd-virt-server.1.txt

diff --git a/Documentation/trace-cmd-virt-server.1.txt 
b/Documentation/trace-cmd-virt-server.1.txt
new file mode 100644
index 000..4168a04
--- /dev/null
+++ b/Documentation/trace-cmd-virt-server.1.txt
@@ -0,0 +1,89 @@
+TRACE-CMD-VIRT-SERVER(1)
+
+
+NAME
+
+trace-cmd-virt-server - listen for incoming connection to record tracing of
+

[PATCH V2 4/5] trace-cmd: Add virt-server mode for a virtualization environment

2013-09-12 Thread Yoshihiro YUNOMAE
Add the virt-server mode for a virtualization environment based on the listen
mode for networking. This mode works like client/server mode over TCP/UDP,
but it uses virtio-serial channel instead of IP network. Using networking for
collecting trace data of guests is generally high overhead caused by processing
of the network stack.

We use virtio-serial for collecting trace data of guests. virtio-serial is a
simple communication path between the guest and the host. Moreover,
since virtio-serial and ftrace can use splice(2), memory copying is not
occurred on the guests. Therefore, total overhead for collecting trace data
of the guests will be reduced. The implementation of clients will be shown
in another patch.

virt-server uses two kinds of virtio-serial I/Fs:
(1) agent-ctl-path(UNIX domain socket)
= control path of an agent trace-cmd each guest
(2) trace-path-cpuX(named pipe)
= trace data path each vcpu

Those I/Fs must be defined as below paths:
(1) /tmp/trace-cmd/virt/agent-ctl-path
(2) /tmp/trace-cmd/virt/guest domain/trace-path-cpuX

If we run virt-server, agent-ctl-path I/F is automatically created because
virt-server operates as a server mode of UNIX domain socket. However,
trace-path-cpuX is not automatically created because we need to separate
trace data for each guests.

When the client uses virtio-serial, the client must notify the server of the
connection. This is because a virtio-serial I/F on the guest is a just character
device. In other words, the server cannot understand whether the client exists
or not even if the client opens the I/F. So, the server using virtio-serial
waits for the connection message MSG_TCONNECT from the client.
The server and the client operate as follows:

 server client
  wait for MSG_TCONNECT
  open virtio-serial I/F
  send MSG_TCONNECT
  receive MSG_TCONNECT +
  send MSG_RCONNECT
+--- receive MSG_RCONNECT
  check tracecmd-V2
  send cpus,pagesize,option(MSG_TINIT)
  receive MSG_TINIT ---+
  print cpus=XXX
  print pagesize=XXX
  understand option
  send port_array
   +--MSG_RINIT- receive MSG_RINIT
  understand port_array
  send meta data(MSG_SENDMETA)
  receive MSG_SENDMETA +
  record meta data
 (snip)
  send a message to finish sending meta data
|   (MSG_FINMETA)
  receive MSG_FINMETA -+
  read block
 --- start sending trace data on child processes ---

 --- When client finishes sending trace data ---
  send MSG_CLOSE
  receive MSG_CLOSE ---+
  close(socket fd)close(socket fd)

How to set up
1. Run virt-server on a host before booting guests
   # trace-cmd virt-server

2. Make guest domain directory
   # mkdir -p /tmp/trace-cmd/virt/domain
   # chmod 710 /tmp/trace-cmd/virt/domain
   # chgrp qemu /tmp/trace-cmd/virt/domain

3. Make FIFO on the host
   # mkfifo /tmp/trace-cmd/virt/domain/trace-path-cpu{0,1,...,X}.{in,out}

4. Set up of virtio-serial pipe of a guest on the host
   Add the following tags to domain XML files.
   # virsh edit domain
   channel type='unix'
  source mode='connect' path='/tmp/trace-cmd/virt/agent-ctl-path'/
  target type='virtio' name='agent-ctl-path'/
   /channel
   channel type='pipe'
  source path='/tmp/trace-cmd/virt/domain/trace-path-cpu0'/
  target type='virtio' name='trace-path-cpu0'/
   /channel
   ... (cpu1, cpu2, ...)

5. Boot the guest
   # virsh start domain

6. Check I/F of virtio-serial on the guest
   # ls /dev/virtio-ports
 ...
 agent-ctl-path
 ...
 trace-path-cpu0
 ...

Next, the user will run trace-cmd with record --virt options or other options
for virtualization on the guest.

This patch adds only minimum features of virt-server as follows:
Features
 - virt-server subcommand
 - Create I/F directory(/tmp/trace-cmd/virt/)
 - Use named pipe I/Fs of virtio-serial for trace data paths
 - Use UNIX domain socket for connecting clients on guests
 - Use splice(2) for collecting trace data of guests

Restrictions
 - Use libvirt when we boot guests

Signed-off-by: Yoshihiro YUNOMAE yoshihiro.yunomae...@hitachi.com
---
 Documentation/trace-cmd-virt-server.1.txt |   89 ++
 trace-cmd.c   |3 
 trace-cmd.h   |2 
 trace-listen.c|  434 -
 trace-msg.c   |  105 +++
 trace-recorder.c  |   54 +++-
 trace-usage.c |   10 +
 7 files changed, 602 insertions(+), 95 deletions(-)
 create mode 100644 Documentation/trace-cmd-virt-server.1.txt

diff --git