Re: [Xen-devel] [RFC PATCH] xentop: add support for qdisks

2015-02-24 Thread Ian Campbell
On Fri, 2015-02-20 at 11:10 -0700, Charles Arnold wrote:
 Now that Xen uses qdisks by default and qemu does not write out
 statistics to sysfs this patch queries the QMP for disk statistics.

I know this patch has been withdrawn but for future reference using
libyajl or some libqmp (if one exists) would be far preferable to ad-hoc
strcmp-ing of the current layout of the presented json.

and the content probably wants to go in a new xenstat_qmp.c or
something, it should work just as well on BSD I think.



___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [RFC PATCH] xentop: add support for qdisks

2015-02-23 Thread Felipe Franciosi
Hi Charles,

It's good to see that someone else is tackling this problem. We have a similar 
problem in XenServer; tapdisk3 is a user space backend (just like qemu-qdisk) 
and therefore libxenstat is unable to pick up any statistics from it. In that 
way, xentop also doesn't display any stats for VBDs.

We tackled this by exposing statistics from tapdisk3 via /dev/shm. Our tools 
then pick up data from there.

You can look at the current code as implemented in tapdisk3 here:
https://github.com/xapi-project/blktap

And for a tool that consumes it here:
https://github.com/xenserver/xsiostat

We are in the process of redesigning this slightly as we wish to break down the 
stats between input and output channels. tapdisk3 takes requests from several 
sources (e.g. blktap2, blkfront, nbd) and uses libaio to submit requests to 
different images. Currently, our code only consider requests coming from 
blkfront (or any other guest pv driver).

After we are finished, we intended to fix libxenstat to understand our format 
and consequently fix the stats as displayed by xentop. If you are committed to 
work on this now, perhaps it's worth touching base and agreeing on the data 
format and interfaces to prevent duplicated work.

Let us know what you think.

Cheers,
Felipe


 -Original Message-
 From: xen-devel-boun...@lists.xen.org [mailto:xen-devel-
 boun...@lists.xen.org] On Behalf Of Charles Arnold
 Sent: 20 February 2015 22:04
 To: xen-devel
 Cc: Ian Campbell
 Subject: Re: [Xen-devel] [RFC PATCH] xentop: add support for qdisks
 
  On 2/20/2015 at 11:10 AM, Charles Arnold wrote:
  Now that Xen uses qdisks by default and qemu does not write out
  statistics to sysfs this patch queries the QMP for disk statistics.
 
 Forget this patch. I assumed the name of the xenstore backend device (eg, 
 xvda,
 hda, etc) would be the same name as used by qemu and it is not.
 
 - Charles
 
 
 
 ___
 Xen-devel mailing list
 Xen-devel@lists.xen.org
 http://lists.xen.org/xen-devel

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] [RFC PATCH] xentop: add support for qdisks

2015-02-20 Thread Charles Arnold
 On 2/20/2015 at 11:10 AM, Charles Arnold wrote: 
 Now that Xen uses qdisks by default and qemu does not write out
 statistics to sysfs this patch queries the QMP for disk statistics.

Forget this patch. I assumed the name of the xenstore backend device
(eg, xvda, hda, etc) would be the same name as used by qemu and it is
not.

- Charles



___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


[Xen-devel] [RFC PATCH] xentop: add support for qdisks

2015-02-20 Thread Charles Arnold
Now that Xen uses qdisks by default and qemu does not write out
statistics to sysfs this patch queries the QMP for disk statistics.

Signed-off-by: Charles Arnold carn...@suse.com

diff --git a/tools/xenstat/libxenstat/src/xenstat_linux.c 
b/tools/xenstat/libxenstat/src/xenstat_linux.c
index 7fdf70a..885d089 100644
--- a/tools/xenstat/libxenstat/src/xenstat_linux.c
+++ b/tools/xenstat/libxenstat/src/xenstat_linux.c
@@ -24,11 +24,15 @@
 #include dirent.h
 #include sys/types.h
 #include sys/stat.h
+#include sys/socket.h
+#include sys/poll.h
+#include sys/un.h
 #include stdio.h
 #include stdlib.h
 #include string.h
 #include unistd.h
 #include regex.h
+#include errno.h
 
 #include xenstat_priv.h
 
@@ -398,6 +402,258 @@ static int read_attributes_vbd(const char *vbd_directory, 
const char *what, char
return num_read;
 }
 
+/* Given an object name look up its value in the buffer */
+static void qmp_lookup_object(unsigned char *buf, char *name, unsigned long 
long *value)
+{
+   unsigned char *ptr;
+   int len;
+
+   *value = 0;
+   len = strlen((char *)name);
+   for (ptr=buf; *ptr; ptr++) {
+   if ( !strncmp((char *)ptr, name, len) ) {
+   ptr += len;
+   while (*ptr == ' ')
+   ++ptr;
+   (void)sscanf((char *)ptr, %llu, value);
+   break;
+   }
+   }
+}
+
+/* Starting at the opening brace of an object, go until the closing is found */
+static unsigned char *qmp_skip_object(unsigned char *obj)
+{
+   unsigned char *end;
+   int brace = 0;
+
+   if ( *obj != '{' )
+   return obj;
+   for ( end=obj; *end; end++ ) {
+   if ( *end == '{' )
+   ++brace;
+   else if ( *end == '}' )
+   --brace;
+   if ( brace = 0 ) {
+   ++end;
+   break;
+   }
+   }
+   return end;
+}
+
+/*
+  Parse disk statistics from QMP
+  A single query-blockstats QMP call will get all disks belonging to the VM.
+  We need to parse that data and get the stats for the vbd we care about.
+*/
+static void qmp_parse(unsigned char *stats, unsigned int domid,
+   unsigned char *vbdname, unsigned int sector_size, xenstat_vbd *vbd)
+{
+   unsigned long long bytes;
+   unsigned char *ptr, *tmp;
+   int vbdlen, vbdfound, tmplen;
+   unsigned char buf[512];
+
+   vbdlen = (int)strlen((const char *)vbdname);
+   vbdfound = 0;
+   /* Example: {return: [{device: xvda, parent: {..., stats: 
{... */
+   for (ptr=stats; *ptr; ptr++) {
+   if ( *ptr == '{' ) {
+   if ( !vbdfound ) {
+   if ( !strncmp((const char *)ptr, 
{\device\:, 10) ) {
+   ptr += 10;
+   while (*ptr == ' ' || *ptr == '')
+   ++ptr;
+   if ( !strncmp((const char *)ptr, (const 
char *)vbdname, vbdlen) ) {
+   vbdfound = 1;
+   ptr += vbdlen;
+   }
+   }
+   }
+   else {
+   ptr = qmp_skip_object(ptr);
+   }
+   }
+   else if ( vbdfound  !strncmp((const char *)ptr,  
\stats\:, 9) ) {
+   ptr += 10;
+   tmp = ptr;
+   ptr = qmp_skip_object(ptr);
+   tmplen = (int)(ptr-tmp);
+   strncpy((char *)buf, (char *)tmp, tmplen);
+   buf[tmplen] = 0;
+   qmp_lookup_object(buf, \rd_bytes\:, bytes);
+   vbd-rd_sects = bytes / sector_size;
+   qmp_lookup_object(buf, \wr_bytes\:, bytes);
+   vbd-wr_sects = bytes / sector_size;
+   qmp_lookup_object(buf, \rd_operations\:, 
vbd-rd_reqs);
+   qmp_lookup_object(buf, \wr_operations\:, 
vbd-wr_reqs);
+   break;
+   }
+   }
+}
+
+/* Write a command via the QMP */
+static size_t qmp_write(int qfd, char *cmd, size_t cmd_len)
+{
+   size_t pos = 0;
+   ssize_t res;
+
+   while (cmd_len  pos) {
+   res = write(qfd, cmd + pos, cmd_len - pos);
+   switch (res) {
+   case -1:
+   if (errno == EINTR || errno == EAGAIN)
+   continue;
+   return 0;
+   case 0:
+   errno = EPIPE;
+   return pos;
+   default:
+   pos += (size_t)res;
+   }
+   }
+   return pos;
+}
+