Re: [PATCH] blockdev: add 'media=cdrom' argument to support usb cdrom emulated as cdrom

2022-12-01 Thread Zhipeng Lu

libvirt issue: https://gitlab.com/libvirt/libvirt/-/issues/261

1、start vm with usb cdrom

  
  
  
  
  


2、 get qemu cmdline


qemu ... -blockdev 
{"driver":"file","filename":"/tmp/cdrom","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"} 
-blockdev 
{"node-name":"libvirt-1-format","read-only":true,"discard":"unmap","driver":"raw","file":"libvirt-1-storage"} 
-device 
{"driver":"usb-storage","bus":"usb.0","port":"1","drive":"libvirt-1-format","id":"usb-disk0","removable":false}

3、 in vm

NAME  MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda 8:00  100M  1 disk
vda   252:00   10G  0 disk
├─vda1252:101G  0 part /boot
└─vda2    252:209G  0 part
  ├─rhel-root 253:008G  0 lvm  /
  └─rhel-swap 253:101G  0 lvm  [SWAP]
lshw -short|grep cdrom -i
No cdrom.

My patch is to solve this problem, usb cdrom emulated as cdrom.



在 2022/12/1 23:35, Markus Armbruster 写道:

luzhipeng  writes:


From: zhipeng Lu 

The drive interface supports media=cdrom so that the usb cdrom
can be emulated as cdrom in qemu, but libvirt deprived the drive
interface, so media=cdrom is added to the blockdev interface to
support usb cdrom emulated as cdrom

Signed-off-by: zhipeng Lu 


What problem are you trying to solve?









Re: [PATCH] blockdev: add 'media=cdrom' argument to support usb cdrom emulated as cdrom

2022-12-03 Thread Zhipeng Lu

Could you give the detail qemu cmdline about usb-bot?

在 2022/12/2 17:40, Paolo Bonzini 写道:

On 12/2/22 03:26, Zhipeng Lu wrote:

NAME  MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda 8:0    0  100M  1 disk
vda   252:0    0   10G  0 disk
├─vda1    252:1    0    1G  0 part /boot
└─vda2    252:2    0    9G  0 part
   ├─rhel-root 253:0    0    8G  0 lvm  /
   └─rhel-swap 253:1    0    1G  0 lvm  [SWAP]
lshw -short|grep cdrom -i
No cdrom.

My patch is to solve this problem, usb cdrom emulated as cdrom.


This is a libvirt bug, it should use usb-bot instead of usb-storage 
together with -blockdev.  Then it can add a scsi-cd device below usb-bot.


Paolo




在 2022/12/1 23:35, Markus Armbruster 写道:

luzhipeng  writes:


From: zhipeng Lu 

The drive interface supports media=cdrom so that the usb cdrom
can be emulated as cdrom in qemu, but libvirt deprived the drive
interface, so media=cdrom is added to the blockdev interface to
support usb cdrom emulated as cdrom

Signed-off-by: zhipeng Lu 


What problem are you trying to solve?

















Re: [PATCH] blockdev: add 'media=cdrom' argument to support usb cdrom emulated as cdrom

2022-12-08 Thread Zhipeng Lu

Thanks.

 -device usb-bot,id=bot0
 -device scsi-{cd,hd},bus=bot0.0,drive=drive0

Qemu implements virtio scsi to emulate scsi controller, but if the 
virtual machine(for example windows guest os) don't install the virtio 
scsi driver, it don't work
i need the function: emulate cdrom in guest, support hotplug and unplug, 
not  depend on virtio driver


have a better idea?

在 2022/12/7 16:39, Paolo Bonzini 写道:

It should be like this:

-device usb-bot,id=bot0
-device scsi-{cd,hd},bus=bot0.0,drive=drive0

Libvirt has the code to generate the options for SCSI controllers, but 
usb-bot only allows one disk attached to it so it's easier to make it a 
 element.


Paolo

Il sab 3 dic 2022, 13:52 Zhipeng Lu <mailto:luzhip...@cestc.cn>> ha scritto:


Could you give the detail qemu cmdline about usb-bot?

在 2022/12/2 17:40, Paolo Bonzini 写道:
 > On 12/2/22 03:26, Zhipeng Lu wrote:
 >> NAME  MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
 >> sda 8:0    0  100M  1 disk
 >> vda   252:0    0   10G  0 disk
 >> ├─vda1    252:1    0    1G  0 part /boot
 >> └─vda2    252:2    0    9G  0 part
 >>    ├─rhel-root 253:0    0    8G  0 lvm  /
 >>    └─rhel-swap 253:1    0    1G  0 lvm  [SWAP]
 >> lshw -short|grep cdrom -i
 >> No cdrom.
 >>
 >> My patch is to solve this problem, usb cdrom emulated as cdrom.
 >
 > This is a libvirt bug, it should use usb-bot instead of usb-storage
 > together with -blockdev.  Then it can add a scsi-cd device below
usb-bot.
 >
 > Paolo
 >
 >>
 >>
 >> 在 2022/12/1 23:35, Markus Armbruster 写道:
 >>> luzhipeng mailto:luzhip...@cestc.cn>> writes:
 >>>
 >>>> From: zhipeng Lu mailto:luzhip...@cestc.cn>>
 >>>>
 >>>> The drive interface supports media=cdrom so that the usb cdrom
 >>>> can be emulated as cdrom in qemu, but libvirt deprived the drive
 >>>> interface, so media=cdrom is added to the blockdev interface to
 >>>> support usb cdrom emulated as cdrom
 >>>>
 >>>> Signed-off-by: zhipeng Lu mailto:luzhip...@cestc.cn>>
 >>>
 >>> What problem are you trying to solve?
 >>>
 >>>
 >>>
 >>
 >>
 >>
 >
 >
 >








[Qemu-devel] [PATCH] qga: Add support network interface statistics in guest-network-get-interfaces command

2017-07-20 Thread ZhiPeng Lu
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us to monitor
and analyze network traffic.

Signed-off-by: ZhiPeng Lu 

v1->v2:
 - correct some spelling mistake and add the stats data to the
   guest-network-get-interfaces command instead of adding a new command.
v2-v3:
 - optimize function implementation
v3->v4:
 - modify compile error
v4->v5:
 - rename some temporary variables and add str_trim_off function for
   calculating the space num in front of the string in guest_get_network_stats
v5->v6:
 - use g_strchug instead of str_trim_off implemented by myself
v6->v7:
 - add implementation for windows
---
 qga/commands-posix.c | 72 +++-
 qga/commands-win32.c | 47 ++
 qga/qapi-schema.json | 38 ++-
 3 files changed, 155 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index d8e4122..b65dd8e 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1639,6 +1639,65 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+static int guest_get_network_stats(const char *name,
+   GuestNetworkInterfaceStat *stats)
+{
+int name_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+name_len = strlen(name);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_dropped;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_dropped;
+char *trim_line;
+trim_line = g_strchug(line);
+if (trim_line[0] == '\0') {
+continue;
+}
+colon = strchr(trim_line, ':');
+if (!colon) {
+continue;
+}
+if (colon - name_len  == trim_line &&
+   strncmp(trim_line, name, name_len) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_dropped = rx_dropped;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_dropped = tx_dropped;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1655,6 +1714,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStat  *interface_stat = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1774,7 +1834,17 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 
 info->value->has_ip_addresses = true;
 
-
+if (!info->value->has_statistics) {
+interface_stat = g_malloc0(sizeof(*interface_stat));
+if (guest_get_network_stats(info->value->name,
+interface_stat) == -1) {
+info->value->has_statistics = false;
+g_free(interface_stat);
+} else {
+info->value->statistics = interface_stat;
+info->value->has_statistics = true;
+}
+}
 }
 
 freeifaddrs(ifap);
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 6f16457..433453d 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -1152,6 +1152,42 @@ out:
 }
 #endif
 
+static DWORD get_interface_index(const char *guid)
+{
+ULONG index;
+DWORD status;
+wchar_t wbuf[512];
+snwprintf(wbuf, sizeof(wbuf), L"\\device\\tcpip_%s", guid);
+wbuf[sizeof(wbuf) - 1] = 0;
+status = GetAdapterIndex (wbuf, &index);
+if (status != NO_ERROR) {
+return (DWORD)~0;
+} else {
+return index;
+

[Qemu-devel] [PATCH v7] qga: Add support network interface statistics in guest-network-get-interfaces command

2017-07-20 Thread ZhiPeng Lu
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us to monitor
and analyze network traffic.

Signed-off-by: ZhiPeng Lu 

v1->v2:
 - correct some spelling mistake and add the stats data to the
   guest-network-get-interfaces command instead of adding a new command.
v2-v3:
 - optimize function implementation
v3->v4:
 - modify compile error
v4->v5:
 - rename some temporary variables and add str_trim_off function for
   calculating the space num in front of the string in guest_get_network_stats
v5->v6:
 - use g_strchug instead of str_trim_off implemented by myself
v6->v7:
 - add implementation for windows
---
 qga/commands-posix.c | 72 +++-
 qga/commands-win32.c | 47 ++
 qga/qapi-schema.json | 38 ++-
 3 files changed, 155 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index d8e4122..b65dd8e 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1639,6 +1639,65 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+static int guest_get_network_stats(const char *name,
+   GuestNetworkInterfaceStat *stats)
+{
+int name_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+name_len = strlen(name);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_dropped;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_dropped;
+char *trim_line;
+trim_line = g_strchug(line);
+if (trim_line[0] == '\0') {
+continue;
+}
+colon = strchr(trim_line, ':');
+if (!colon) {
+continue;
+}
+if (colon - name_len  == trim_line &&
+   strncmp(trim_line, name, name_len) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_dropped = rx_dropped;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_dropped = tx_dropped;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1655,6 +1714,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStat  *interface_stat = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1774,7 +1834,17 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 
 info->value->has_ip_addresses = true;
 
-
+if (!info->value->has_statistics) {
+interface_stat = g_malloc0(sizeof(*interface_stat));
+if (guest_get_network_stats(info->value->name,
+interface_stat) == -1) {
+info->value->has_statistics = false;
+g_free(interface_stat);
+} else {
+info->value->statistics = interface_stat;
+info->value->has_statistics = true;
+}
+}
 }
 
 freeifaddrs(ifap);
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 6f16457..433453d 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -1152,6 +1152,42 @@ out:
 }
 #endif
 
+static DWORD get_interface_index(const char *guid)
+{
+ULONG index;
+DWORD status;
+wchar_t wbuf[512];
+snwprintf(wbuf, sizeof(wbuf), L"\\device\\tcpip_%s", guid);
+wbuf[sizeof(wbuf) - 1] = 0;
+status = GetAdapterIndex (wbuf, &index);
+if (status != NO_ERROR) {
+return (DWORD)~0;
+} else {
+return index;
+

[Qemu-devel] [PATCH] fsdev: fix memory leak in main()

2017-07-26 Thread ZhiPeng Lu
@rpath and @ sock_name are not freed and leaked.

Signed-off-by: Zhipeng Lu lu.zhip...@zte.com.cn
---
 fsdev/virtfs-proxy-helper.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
index 6c066ec..8e48500 100644
--- a/fsdev/virtfs-proxy-helper.c
+++ b/fsdev/virtfs-proxy-helper.c
@@ -1162,6 +1162,8 @@ int main(int argc, char **argv)
 
 process_requests(sock);
 error:
+g_free(rpath);
+g_free(sock_name);
 do_log(LOG_INFO, "Done\n");
 closelog();
 return 0;
-- 
1.8.3.1





[Qemu-devel] [PATCH RESEND v6] qga: Add support network interface statistics in guest-network-get-interfaces command

2017-07-04 Thread ZhiPeng Lu
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us to monitor
and analyze network traffic.

Signed-off-by: ZhiPeng Lu 
---
 qga/commands-posix.c | 80 +++-
 qga/qapi-schema.json | 38 -
 2 files changed, 116 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 915df9e..233b024 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1638,6 +1638,73 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+
+static int str_trim_off(const char *s, int off, int lmt)
+{
+for (; off < lmt; ++off) {
+if (!isspace(s[off])) {
+break;
+}
+}
+return off;
+}
+
+static int guest_get_network_stats(const char *name,
+   GuestNetworkInterfaceStat *stats)
+{
+int name_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+name_len = strlen(name);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_dropped;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_dropped;
+int trim_off;
+colon = strchr(line, ':');
+if (!colon) {
+continue;
+}
+trim_off = str_trim_off(line, 0, strlen(line));
+if (colon - name_len - trim_off == line &&
+   strncmp(line + trim_off, name, colon - line - trim_off) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_dropped = rx_dropped;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_dropped = tx_dropped;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1654,6 +1721,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStat  *interface_stat = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1773,7 +1841,17 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 
 info->value->has_ip_addresses = true;
 
-
+if (!info->value->has_statistics) {
+interface_stat = g_malloc0(sizeof(*interface_stat));
+if (guest_get_network_stats(info->value->name,
+interface_stat) == -1) {
+info->value->has_statistics = false;
+g_free(interface_stat);
+} else {
+info->value->statistics = interface_stat;
+info->value->has_statistics = true;
+}
+}
 }
 
 freeifaddrs(ifap);
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index a02dbf2..948219b 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -635,6 +635,38 @@
'prefix': 'int'} }
 
 ##
+# @GuestNetworkInterfaceStat:
+#
+# @rx-bytes: total bytes received
+#
+# @rx-packets: total packets received
+#
+# @rx-errs: bad packets received
+#
+# @rx-dropped: receiver dropped packets
+#
+# @tx-bytes: total bytes transmitted
+#
+# @tx-packets: total packets transmitted
+#
+# @tx-errs: packet transmit problems
+#
+# @tx-dropped: dropped packets transmitted
+#
+# Since: 2.10
+##
+{ 'struct': 'GuestNetworkInterfaceStat',
+  'data': {'rx-bytes': 'uint64',
+'rx-packets': 'uint64',
+'rx-errs': 'uint64',
+'rx-dropped': 'uint64',
+'tx-bytes': 'uint64',
+'tx

[Qemu-devel] [PATCH] vhost: don't set vring call fd to -1 in vhost_virtqueue_start for vhost-user

2017-08-20 Thread ZhiPeng Lu
commit 96a3d98d2cdbd897ff5ab33427aa4cfb94077665 (vhost: don't set vring call
if no vector) set vring call fd to -1 for drivers does not use interrupt
at all(e.g virtio-net pmd). That patch setting vring call fd to -1 cause
the network to not work when running dpdk in the guest. The openvswitch port
status is down by executing the command "ovs-vsctl list interface"
in host of running the guest. The network is ok if it doesn't set vring call fd
to -1 in vhost_virtqueue_start.
The patch doesn't set vring call fd to -1 for vhost-user.

Signed-off-by: ZhiPeng Lu 
---
 hw/virtio/vhost.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 6eddb09..bb8db7d 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1098,7 +1098,8 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
 
 if (k->query_guest_notifiers &&
 k->query_guest_notifiers(qbus->parent) &&
-virtio_queue_vector(vdev, idx) == VIRTIO_NO_VECTOR) {
+virtio_queue_vector(vdev, idx) == VIRTIO_NO_VECTOR &&
+vdev->use_guest_notifier_mask) {
 file.fd = -1;
 r = dev->vhost_ops->vhost_set_vring_call(dev, &file);
 if (r) {
-- 
1.8.3.1





[Qemu-devel] [PATCH v2] qga: Add support network interface statistics in guest-network-get-interfaces command

2017-04-20 Thread ZhiPeng Lu
we can get the  network inetrface statistics inside  a virtual machine by
guest-network-get-interfaces command.
it is very userful for us to monitor and analyze network traff.

Signed-off-by: ZhiPeng Lu 
Signed-off-by: DanielP.Berrange 
Reviewed-by: EricBlake  
---
 qga/commands-posix.c | 73 +++-
 qga/qapi-schema.json | 28 +++-
 2 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 915df9e..1c34279 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1638,6 +1638,65 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+ static int guest_get_network_stats(const char *path,
+   GuestNetworkInterfaceStat *stats)
+{
+int path_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+path_len = strlen(path);
+while (getline(&line, &n, fp) != -1) {
+int64_t dummy;
+int64_t rx_bytes;
+int64_t rx_packets;
+int64_t rx_errs;
+int64_t rx_drop;
+int64_t tx_bytes;
+int64_t tx_packets;
+int64_t tx_errs;
+int64_t tx_drop;
+
+  /* The line looks like:
+   *"   eth0:..."
+   *Split it at the colon.
+   */
+colon = strchr(line, ':');
+if (!colon) {
+continue;
+}
+*colon = '\0';
+if (colon - path_len >= line && strcmp(colon - path_len, path) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_drop,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_drop,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_drop = rx_drop;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_drop = tx_drop;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1654,6 +1713,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStatList  *interface_stat_item = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1770,9 +1830,20 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 } else {
 (*address_list)->next = address_item;
 }
-
 info->value->has_ip_addresses = true;
 
+if (!info->value->has_interface_statics) {
+interface_stat_item = g_malloc0(sizeof(*interface_stat_item));
+interface_stat_item->value = g_malloc0(
+   sizeof(*interface_stat_item->value));
+if (guest_get_network_stats(info->value->name,
+interface_stat_item->value) == -1) {
+error_setg_errno(errp, errno, "guest_get_network_stats 
failed");
+goto error;
+}
+info->value->interface_statics = interface_stat_item;
+}
+info->value->has_interface_statics = true;
 
 }
 
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index a02dbf2..44bcced 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -635,6 +635,31 @@
'prefix': 'int'} }
 
 ##
+# @GuestNetworkInterfaceStat:
+#
+# @rx-bytes: received bytes of interface
+# @rx-packets: received packets of interface
+# @rx-errs: received error packets of interface
+# @rx-drop: received drop packets of interface
+#
+# @tx-bytes: send bytes of interface
+# @tx-packets: send packets of interface
+# @tx-errs: send error packets of interface
+# @tx-drop: send drop packets of interface
+# Since: 2.10
+##
+{ 'struct': 'GuestNetworkInterfaceStat',
+  'data': {'rx-bytes': 'uint64',
+'rx-packets': 'uint64',
+'rx-errs': 'uint64',
+'rx-drop': 'uint64',
+'

[Qemu-devel] [PATCH] qga: Add support network interface statistics in guest-network-get-interfaces command

2017-04-20 Thread ZhiPeng Lu
we can get the  network interface statistics inside  a virtual machine by
guest-network-get-interfaces command.
it is very userful for us to monitor and analyze network traff.

Signed-off-by: ZhiPeng Lu 
Signed-off-by: DanielP.Berrange 
Reviewed-by: EricBlake  
---
 qga/commands-posix.c | 73 +++-
 qga/qapi-schema.json | 28 +++-
 2 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 915df9e..0c48707 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1638,6 +1638,65 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+ static int guest_get_network_stats(const char *path,
+   GuestNetworkInterfaceStat *stats)
+{
+int path_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+path_len = strlen(path);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_drop;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_drop;
+
+  /* The line looks like:
+   *"   eth0:..."
+   *Split it at the colon.
+   */
+colon = strchr(line, ':');
+if (!colon) {
+continue;
+}
+*colon = '\0';
+if (colon - path_len >= line && strcmp(colon - path_len, path) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_drop,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_drop,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_drop = rx_drop;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_drop = tx_drop;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1654,6 +1713,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStatList  *interface_stat_item = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1770,9 +1830,20 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 } else {
 (*address_list)->next = address_item;
 }
-
 info->value->has_ip_addresses = true;
 
+if (!info->value->has_interface_statics) {
+interface_stat_item = g_malloc0(sizeof(*interface_stat_item));
+interface_stat_item->value = g_malloc0(
+   sizeof(*interface_stat_item->value));
+if (guest_get_network_stats(info->value->name,
+interface_stat_item->value) == -1) {
+error_setg_errno(errp, errno, "guest_get_network_stats 
failed");
+goto error;
+}
+info->value->interface_statics = interface_stat_item;
+}
+info->value->has_interface_statics = true;
 
 }
 
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index a02dbf2..44bcced 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -635,6 +635,31 @@
'prefix': 'int'} }
 
 ##
+# @GuestNetworkInterfaceStat:
+#
+# @rx-bytes: received bytes of interface
+# @rx-packets: received packets of interface
+# @rx-errs: received error packets of interface
+# @rx-drop: received drop packets of interface
+#
+# @tx-bytes: send bytes of interface
+# @tx-packets: send packets of interface
+# @tx-errs: send error packets of interface
+# @tx-drop: send drop packets of interface
+# Since: 2.10
+##
+{ 'struct': 'GuestNetworkInterfaceStat',
+  'data': {'rx-bytes': 'uint64',
+'rx-packets': 'uint64',
+'rx-errs': 'uint64',
+'rx-drop': 'uint64',
+  

[Qemu-devel] [PATCH v3] qga: Add support network interface statistics in

2017-04-21 Thread ZhiPeng Lu
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us to monitor
and analyze network traffic.

Signed-off-by: ZhiPeng Lu 
Signed-off-by: Daniel P. Berrange 
---
 qga/commands-posix.c | 71 +++-
 qga/qapi-schema.json | 38 +++-
 2 files changed, 107 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 915df9e..1e35340 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1638,6 +1638,65 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+ static int guest_get_network_stats(const char *path,
+   GuestNetworkInterfaceStat *stats)
+{
+int path_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+path_len = strlen(path);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_dropped;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_dropped;
+
+  /* The line looks like:
+   *"   eth0:..."
+   *Split it at the colon.
+   */
+colon = strchr(line, ':');
+if (!colon) {
+continue;
+}
+*colon = '\0';
+if (colon - path_len >= line && strcmp(colon - path_len, path) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_dropped = rx_dropped;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_dropped = tx_dropped;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1654,6 +1713,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStat  *interface_stat = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1773,7 +1833,16 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 
 info->value->has_ip_addresses = true;
 
-
+if (!info->value->has_statistics) {
+interface_stat = g_malloc0(sizeof(*interface_stat));
+if (guest_get_network_stats(info->value->name,
+interface_stat) == -1) {
+error_setg_errno(errp, errno, "guest_get_network_stats 
failed");
+goto error;
+}
+info->value->statistics = interface_stat;
+info->value->has_statistics = true;
+}
 }
 
 freeifaddrs(ifap);
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index a02dbf2..3f5927c 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -635,6 +635,38 @@
'prefix': 'int'} }
 
 ##
+# @GuestNetworkInterfaceStat:
+#
+# @rx-bytes: total bytes received
+#
+# @rx-packets: total packets received
+#
+# @rx-errs: bad packets received
+#
+# @rx-dropped: receiver dropped packets
+#
+# @tx-bytes: total bytes transmitted
+#
+# @tx-packets: total packets transmitted
+#
+# @tx-errs: packet transmit problems
+#
+# @tx-dropped: dropped packets transmitted
+#
+# Since: 2.10
+##
+{ 'struct': 'GuestNetworkInterfaceStat',
+  'data': {'rx-bytes': 'uint64',
+'rx-packets': 'uint64',
+'rx-errs': 'uint64',
+'rx-dropped': 'uint64',
+'tx-bytes': 'uint64',
+'tx-packets': 'uint64',
+'tx-errs': 'uint64',
+'tx-dropped': 'uint64'
+   } }
+

[Qemu-devel] [PATCH v3] qga: Add support network interface statistics in

2017-04-21 Thread ZhiPeng Lu
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us to monitor
and analyze network traffic.

Signed-off-by: ZhiPeng Lu 
Signed-off-by: Daniel P. Berrange 
---
 qga/commands-posix.c | 71 +++-
 qga/qapi-schema.json | 38 +++-
 2 files changed, 107 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 915df9e..1e35340 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1638,6 +1638,65 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+ static int guest_get_network_stats(const char *path,
+   GuestNetworkInterfaceStat *stats)
+{
+int path_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+path_len = strlen(path);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_dropped;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_dropped;
+
+  /* The line looks like:
+   *"   eth0:..."
+   *Split it at the colon.
+   */
+colon = strchr(line, ':');
+if (!colon) {
+continue;
+}
+*colon = '\0';
+if (colon - path_len >= line && strcmp(colon - path_len, path) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_dropped = rx_dropped;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_dropped = tx_dropped;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1654,6 +1713,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStat  *interface_stat = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1773,7 +1833,16 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 
 info->value->has_ip_addresses = true;
 
-
+if (!info->value->has_statistics) {
+interface_stat = g_malloc0(sizeof(*interface_stat));
+if (guest_get_network_stats(info->value->name,
+interface_stat) == -1) {
+error_setg_errno(errp, errno, "guest_get_network_stats 
failed");
+goto error;
+}
+info->value->statistics = interface_stat;
+info->value->has_statistics = true;
+}
 }
 
 freeifaddrs(ifap);
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index a02dbf2..3f5927c 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -635,6 +635,38 @@
'prefix': 'int'} }
 
 ##
+# @GuestNetworkInterfaceStat:
+#
+# @rx-bytes: total bytes received
+#
+# @rx-packets: total packets received
+#
+# @rx-errs: bad packets received
+#
+# @rx-dropped: receiver dropped packets
+#
+# @tx-bytes: total bytes transmitted
+#
+# @tx-packets: total packets transmitted
+#
+# @tx-errs: packet transmit problems
+#
+# @tx-dropped: dropped packets transmitted
+#
+# Since: 2.10
+##
+{ 'struct': 'GuestNetworkInterfaceStat',
+  'data': {'rx-bytes': 'uint64',
+'rx-packets': 'uint64',
+'rx-errs': 'uint64',
+'rx-dropped': 'uint64',
+'tx-bytes': 'uint64',
+'tx-packets': 'uint64',
+'tx-errs': 'uint64',
+'tx-dropped': 'uint64'
+   } }
+

[Qemu-devel] [PATCH v4] qga: Add support network interface statistics in

2017-04-24 Thread ZhiPeng Lu
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us to monitor
and analyze network traffic.

Signed-off-by: ZhiPeng Lu 
Signed-off-by: Daniel P. Berrange 
---
 qga/commands-posix.c | 71 +++-
 qga/qapi-schema.json | 38 +++-
 2 files changed, 107 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 915df9e..1e35340 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1638,6 +1638,65 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+ static int guest_get_network_stats(const char *path,
+   GuestNetworkInterfaceStat *stats)
+{
+int path_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+path_len = strlen(path);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_dropped;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_dropped;
+
+  /* The line looks like:
+   *"   eth0:..."
+   *Split it at the colon.
+   */
+colon = strchr(line, ':');
+if (!colon) {
+continue;
+}
+*colon = '\0';
+if (colon - path_len >= line && strcmp(colon - path_len, path) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_dropped = rx_dropped;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_dropped = tx_dropped;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1654,6 +1713,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStat  *interface_stat = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1773,7 +1833,16 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 
 info->value->has_ip_addresses = true;
 
-
+if (!info->value->has_statistics) {
+interface_stat = g_malloc0(sizeof(*interface_stat));
+if (guest_get_network_stats(info->value->name,
+interface_stat) == -1) {
+error_setg_errno(errp, errno, "guest_get_network_stats 
failed");
+goto error;
+}
+info->value->statistics = interface_stat;
+info->value->has_statistics = true;
+}
 }
 
 freeifaddrs(ifap);
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index a02dbf2..948219b 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -635,6 +635,38 @@
'prefix': 'int'} }
 
 ##
+# @GuestNetworkInterfaceStat:
+#
+# @rx-bytes: total bytes received
+#
+# @rx-packets: total packets received
+#
+# @rx-errs: bad packets received
+#
+# @rx-dropped: receiver dropped packets
+#
+# @tx-bytes: total bytes transmitted
+#
+# @tx-packets: total packets transmitted
+#
+# @tx-errs: packet transmit problems
+#
+# @tx-dropped: dropped packets transmitted
+#
+# Since: 2.10
+##
+{ 'struct': 'GuestNetworkInterfaceStat',
+  'data': {'rx-bytes': 'uint64',
+'rx-packets': 'uint64',
+'rx-errs': 'uint64',
+'rx-dropped': 'uint64',
+'tx-bytes': 'uint64',
+'tx-packets': 'uint64',
+'tx-errs': 'uint64',
+'tx-dropped': 'uint64'
+   } }
+

[Qemu-devel] [PATCH v5] qga: Add support network interface statistics in guest-network-get-interfaces command

2017-04-27 Thread ZhiPeng Lu
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us to monitor
and analyze network traffic.

Signed-off-by: ZhiPeng Lu 
Signed-off-by: Daniel P. Berrange 
---
 qga/commands-posix.c | 68 +++-
 qga/qapi-schema.json | 38 -
 2 files changed, 104 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 915df9e..8dbf30e 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1638,6 +1638,61 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+ static int guest_get_network_stats(const char *name,
+   GuestNetworkInterfaceStat *stats)
+{
+int name_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+name_len = strlen(name);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_dropped;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_dropped;
+
+colon = strchr(line, ':');
+if (!colon) {
+continue;
+}
+*colon = '\0';
+if (colon - name_len >= line && strcmp(colon - name_len, name) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_dropped = rx_dropped;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_dropped = tx_dropped;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1654,6 +1709,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStat  *interface_stat = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1773,7 +1829,17 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 
 info->value->has_ip_addresses = true;
 
-
+if (!info->value->has_statistics) {
+interface_stat = g_malloc0(sizeof(*interface_stat));
+if (guest_get_network_stats(info->value->name,
+interface_stat) == -1) {
+info->value->has_statistics = false;
+g_free(interface_stat);
+} else {
+info->value->statistics = interface_stat;
+info->value->has_statistics = true;
+}
+}
 }
 
 freeifaddrs(ifap);
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index a02dbf2..948219b 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -635,6 +635,38 @@
'prefix': 'int'} }
 
 ##
+# @GuestNetworkInterfaceStat:
+#
+# @rx-bytes: total bytes received
+#
+# @rx-packets: total packets received
+#
+# @rx-errs: bad packets received
+#
+# @rx-dropped: receiver dropped packets
+#
+# @tx-bytes: total bytes transmitted
+#
+# @tx-packets: total packets transmitted
+#
+# @tx-errs: packet transmit problems
+#
+# @tx-dropped: dropped packets transmitted
+#
+# Since: 2.10
+##
+{ 'struct': 'GuestNetworkInterfaceStat',
+  'data': {'rx-bytes': 'uint64',
+'rx-packets': 'uint64',
+'rx-errs': 'uint64',
+'rx-dropped': 'uint64',
+'tx-bytes': 'uint64',
+'tx-packets': 'uint64',
+'tx-errs': 'uint64',
+'tx-dropped': 'uint64'
+   } }
+
+##
 # @GuestNetworkInterface:
 #
 # @name: The name of interface 

[Qemu-devel] [PATCH v6] qga: Add support network interface statistics in guest-network-get-interfaces command

2017-04-27 Thread ZhiPeng Lu
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us to monitor
and analyze network traffic.

Signed-off-by: ZhiPeng Lu 
Signed-off-by: Daniel P. Berrange 
---
 qga/commands-posix.c | 80 +++-
 qga/qapi-schema.json | 38 -
 2 files changed, 116 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 915df9e..233b024 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1638,6 +1638,73 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+
+static int str_trim_off(const char *s, int off, int lmt)
+{
+for (; off < lmt; ++off) {
+if (!isspace(s[off])) {
+break;
+}
+}
+return off;
+}
+
+static int guest_get_network_stats(const char *name,
+   GuestNetworkInterfaceStat *stats)
+{
+int name_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+name_len = strlen(name);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_dropped;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_dropped;
+int trim_off;
+colon = strchr(line, ':');
+if (!colon) {
+continue;
+}
+trim_off = str_trim_off(line, 0, strlen(line));
+if (colon - name_len - trim_off == line &&
+   strncmp(line + trim_off, name, colon - line - trim_off) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_dropped = rx_dropped;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_dropped = tx_dropped;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1654,6 +1721,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStat  *interface_stat = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1773,7 +1841,17 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 
 info->value->has_ip_addresses = true;
 
-
+if (!info->value->has_statistics) {
+interface_stat = g_malloc0(sizeof(*interface_stat));
+if (guest_get_network_stats(info->value->name,
+interface_stat) == -1) {
+info->value->has_statistics = false;
+g_free(interface_stat);
+} else {
+info->value->statistics = interface_stat;
+info->value->has_statistics = true;
+}
+}
 }
 
 freeifaddrs(ifap);
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index a02dbf2..948219b 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -635,6 +635,38 @@
'prefix': 'int'} }
 
 ##
+# @GuestNetworkInterfaceStat:
+#
+# @rx-bytes: total bytes received
+#
+# @rx-packets: total packets received
+#
+# @rx-errs: bad packets received
+#
+# @rx-dropped: receiver dropped packets
+#
+# @tx-bytes: total bytes transmitted
+#
+# @tx-packets: total packets transmitted
+#
+# @tx-errs: packet transmit problems
+#
+# @tx-dropped: dropped packets transmitted
+#
+# Since: 2.10
+##
+{ 'struct': 'GuestNetworkInterfaceStat',
+  'data': {'rx-bytes': 'uint64',
+'rx-packets': 'uint64',
+'rx-errs': 'uint64',
+'rx-dropped': 'uint64',
+'tx-bytes': 'uint64&#x

[Qemu-devel] [PATCH] hmp: add 'info virtio-pci-status id' command

2017-05-01 Thread ZhiPeng Lu
Add command to  query a virtio pci device status.
we can get id of the virtio pci device by 'info pci' command.
HMP Test case:
==
virsh # qemu-monitor-command --hmp 3 info pci
  Bus  0, device   3, function 0:
Ethernet controller: PCI device 1af4:1000
  IRQ 11.
  BAR0: I/O at 0xc000 [0xc03f].
  BAR1: 32 bit memory at 0xfebd1000 [0xfebd1fff].
  BAR4: 64 bit prefetchable memory at 0xfe00 [0xfe003fff].
  BAR6: 32 bit memory at 0x [0x0003fffe].
  id "net0"
  Bus  0, device   4, function 0:
USB controller: PCI device 8086:24cd
  IRQ 11.
  BAR0: 32 bit memory at 0xfebd2000 [0xfebd2fff].
  id "usb"
virsh # qemu-monitor-command 3  --hmp "info virtio-pci-status net0"
status=15

virsh # qemu-monitor-command 3  --hmp "info virtio-pci-status usb"
the 'info virtio_pci_status' command only supports virtio pci devices

Signed-off-by: ZhiPeng Lu 
---
 hmp-commands-info.hx| 14 ++
 hw/pci/pci-stub.c   |  6 ++
 hw/virtio/virtio-pci.c  | 47 +++
 include/sysemu/sysemu.h |  1 +
 4 files changed, 68 insertions(+)

diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index a53f105..7b9c4db 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -815,6 +815,20 @@ ETEXI
 .cmd = hmp_info_vm_generation_id,
 },
 
+{
+.name   = "virtio-pci-status",
+.args_type  = "id:s",
+.params = "id",
+.help   = "show virtio pci device  status",
+.cmd= hmp_info_virtio_pci_status,
+},
+
+STEXI
+@item info virtio-pci-status  @var{id}
+@findex virtio-pci-status
+Show status about virtio pci device
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/hw/pci/pci-stub.c b/hw/pci/pci-stub.c
index 36d2c43..3609a52 100644
--- a/hw/pci/pci-stub.c
+++ b/hw/pci/pci-stub.c
@@ -35,3 +35,9 @@ void hmp_pcie_aer_inject_error(Monitor *mon, const QDict 
*qdict)
 {
 monitor_printf(mon, "PCI devices not supported\n");
 }
+
+void hmp_info_virtio_pci_status(Monitor *mon, const QDict *qdict)
+{
+monitor_printf(mon, "PCI devices not supported\n");
+}
+
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index f9b7244..5fa862b 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -37,6 +37,7 @@
 #include "qemu/range.h"
 #include "hw/virtio/virtio-bus.h"
 #include "qapi/visitor.h"
+#include "monitor/monitor.h"
 
 #define VIRTIO_PCI_REGION_SIZE(dev) 
VIRTIO_PCI_CONFIG_OFF(msix_present(dev))
 
@@ -50,6 +51,7 @@ static void virtio_pci_bus_new(VirtioBusState *bus, size_t 
bus_size,
VirtIOPCIProxy *dev);
 static void virtio_pci_reset(DeviceState *qdev);
 
+static void query_virtio_pci_status(Monitor *mon, const char *id);
 /* virtio device */
 /* DeviceState to VirtIOPCIProxy. For use off data-path. TODO: use QOM. */
 static inline VirtIOPCIProxy *to_virtio_pci_proxy(DeviceState *d)
@@ -2556,6 +2558,51 @@ static void virtio_pci_bus_new(VirtioBusState *bus, 
size_t bus_size,
 virtio_bus_name);
 }
 
+static void query_virtio_pci_status(Monitor *mon, const char *id)
+{
+int ret = 0, i = 0;
+PCIDevice *dev = NULL;
+hwaddr addr = 0;
+uint8_t val = 0;
+const char *devtype = NULL;
+
+ret = pci_qdev_find_device(id, &dev);
+if (ret) {
+monitor_printf(mon, "Can not find device %s\n", id);
+return;
+}
+devtype = object_get_typename(OBJECT(dev));
+if (strncmp("virtio-", devtype, 7) == 0) {
+for (i = 0; i < PCI_NUM_REGIONS; i++) {
+if (dev->io_regions[i].type == PCI_BASE_ADDRESS_SPACE_IO) {
+addr = dev->io_regions[i].addr;
+break;
+}
+}
+if (addr != -1 && addr != 0) {
+address_space_rw(&address_space_io, addr + VIRTIO_PCI_STATUS,
+MEMTXATTRS_UNSPECIFIED, &val, 1, 0);
+if (val & VIRTIO_CONFIG_S_DRIVER_OK) {
+fprintf(stderr, "driver is ok\n");
+} else {
+fprintf(stderr, "driver is not ok\n");
+}
+monitor_printf(mon, "status=%d", val);
+} else {
+monitor_printf(mon, "status=%d", val);
+}
+} else {
+monitor_printf(mon, "the 'info virtio_pci_status' command "
+   "only supports virtio pci devices");
+}
+}
+
+void hmp_info_virtio_pci_status(Monitor *mon, const QDict *qdict)
+{
+const char *id = qdict_get_try_str(qdict, "id");
+query_virtio_pci_status(mon, id);
+}
+
 static void virtio_pci_bus_class_init(ObjectClass *kl

[Qemu-devel] [PATCH] qga: Add support network interface statistics in guest-network-get-interfaces command

2017-07-19 Thread ZhiPeng Lu
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us to monitor
and analyze network traffic.

Signed-off-by: ZhiPeng Lu 
---
 qga/commands-posix.c | 72 +++-
 qga/qapi-schema.json | 38 ++-
 2 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index d8e4122..b65dd8e 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1639,6 +1639,65 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+static int guest_get_network_stats(const char *name,
+   GuestNetworkInterfaceStat *stats)
+{
+int name_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+name_len = strlen(name);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_dropped;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_dropped;
+char *trim_line;
+trim_line = g_strchug(line);
+if (trim_line[0] == '\0') {
+continue;
+}
+colon = strchr(trim_line, ':');
+if (!colon) {
+continue;
+}
+if (colon - name_len  == trim_line &&
+   strncmp(trim_line, name, name_len) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_dropped = rx_dropped;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_dropped = tx_dropped;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1655,6 +1714,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStat  *interface_stat = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1774,7 +1834,17 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 
 info->value->has_ip_addresses = true;
 
-
+if (!info->value->has_statistics) {
+interface_stat = g_malloc0(sizeof(*interface_stat));
+if (guest_get_network_stats(info->value->name,
+interface_stat) == -1) {
+info->value->has_statistics = false;
+g_free(interface_stat);
+} else {
+info->value->statistics = interface_stat;
+info->value->has_statistics = true;
+}
+}
 }
 
 freeifaddrs(ifap);
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 03743ab..f12c3ca 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -643,6 +643,38 @@
'prefix': 'int'} }
 
 ##
+# @GuestNetworkInterfaceStat:
+#
+# @rx-bytes: total bytes received
+#
+# @rx-packets: total packets received
+#
+# @rx-errs: bad packets received
+#
+# @rx-dropped: receiver dropped packets
+#
+# @tx-bytes: total bytes transmitted
+#
+# @tx-packets: total packets transmitted
+#
+# @tx-errs: packet transmit problems
+#
+# @tx-dropped: dropped packets transmitted
+#
+# Since: 2.10
+##
+{ 'struct': 'GuestNetworkInterfaceStat',
+  'data': {'rx-bytes': 'uint64',
+'rx-packets': 'uint64',
+'rx-errs': 'uint64',
+'rx-dropped': 'uint64',
+'tx-bytes': 'uint64',
+'tx-packets': 'uint64',
+'tx-errs': 'uint64',
+'tx-dropped': 'uint64'
+ 

[Qemu-devel] [PATCH v6] qga: Add support network interface statistics in guest-network-get-interfaces command

2017-07-19 Thread ZhiPeng Lu
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us to monitor
and analyze network traffic.

Signed-off-by: ZhiPeng Lu 

v1->v2:
 - correct some spelling mistake and add the stats data to the
   guest-network-get-interfaces command instead of adding a new command.
v2-v3:
 - optimize function implementation
v3->v4:
 - modify compile error
v4->v5:
 - rename some temporary variables and add str_trim_off function for
   calculating the space num in front of the string in guest_get_network_stats
v5->v6:
 - use g_strchug instead of str_trim_off implemented by myself
---
 qga/commands-posix.c | 72 +++-
 qga/qapi-schema.json | 38 ++-
 2 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index d8e4122..b65dd8e 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1639,6 +1639,65 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+static int guest_get_network_stats(const char *name,
+   GuestNetworkInterfaceStat *stats)
+{
+int name_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+name_len = strlen(name);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_dropped;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_dropped;
+char *trim_line;
+trim_line = g_strchug(line);
+if (trim_line[0] == '\0') {
+continue;
+}
+colon = strchr(trim_line, ':');
+if (!colon) {
+continue;
+}
+if (colon - name_len  == trim_line &&
+   strncmp(trim_line, name, name_len) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_dropped = rx_dropped;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_dropped = tx_dropped;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1655,6 +1714,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStat  *interface_stat = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1774,7 +1834,17 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 
 info->value->has_ip_addresses = true;
 
-
+if (!info->value->has_statistics) {
+interface_stat = g_malloc0(sizeof(*interface_stat));
+if (guest_get_network_stats(info->value->name,
+interface_stat) == -1) {
+info->value->has_statistics = false;
+g_free(interface_stat);
+} else {
+info->value->statistics = interface_stat;
+info->value->has_statistics = true;
+}
+}
 }
 
 freeifaddrs(ifap);
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 03743ab..4ad5c57 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -643,6 +643,38 @@
'prefix': 'int'} }
 
 ##
+# @GuestNetworkInterfaceStat:
+#
+# @rx-bytes: total bytes received
+#
+# @rx-packets: total packets received
+#
+# @rx-errs: bad packets received
+#
+# @rx-dropped: receiver dropped packets
+#
+# @tx-bytes: total bytes transmitted
+#
+# @tx-packets: total packets transmitted
+#
+# @tx-errs: packet transmit problems
+#
+# @tx-dropped: dropped packets transmitted
+#
+# Since: 2.11
+##
+{ 'struct': 'GuestNetworkInterfaceSt

[Qemu-devel] [PATCH v7 RESEND] qga: Add support network interface statistics in guest-network-get-interfaces command

2017-09-11 Thread ZhiPeng Lu
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us to monitor
and analyze network traffic.

Signed-off-by: ZhiPeng Lu 

v1->v2:
 - correct some spelling mistake and add the stats data to the
   guest-network-get-interfaces command instead of adding a new command.
v2-v3:
 - optimize function implementation
v3->v4:
 - modify compile error
v4->v5:
 - rename some temporary variables and add str_trim_off function for
   calculating the space num in front of the string in guest_get_network_stats
v5->v6:
 - use g_strchug instead of str_trim_off implemented by myself
v6->v7:
 - add implementation for windows
---
 qga/commands-posix.c | 72 +++-
 qga/commands-win32.c | 47 ++
 qga/qapi-schema.json | 38 ++-
 3 files changed, 155 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index d8e4122..b65dd8e 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1639,6 +1639,65 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+static int guest_get_network_stats(const char *name,
+   GuestNetworkInterfaceStat *stats)
+{
+int name_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+name_len = strlen(name);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_dropped;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_dropped;
+char *trim_line;
+trim_line = g_strchug(line);
+if (trim_line[0] == '\0') {
+continue;
+}
+colon = strchr(trim_line, ':');
+if (!colon) {
+continue;
+}
+if (colon - name_len  == trim_line &&
+   strncmp(trim_line, name, name_len) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_dropped = rx_dropped;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_dropped = tx_dropped;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1655,6 +1714,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStat  *interface_stat = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1774,7 +1834,17 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 
 info->value->has_ip_addresses = true;
 
-
+if (!info->value->has_statistics) {
+interface_stat = g_malloc0(sizeof(*interface_stat));
+if (guest_get_network_stats(info->value->name,
+interface_stat) == -1) {
+info->value->has_statistics = false;
+g_free(interface_stat);
+} else {
+info->value->statistics = interface_stat;
+info->value->has_statistics = true;
+}
+}
 }
 
 freeifaddrs(ifap);
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 6f16457..433453d 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -1152,6 +1152,42 @@ out:
 }
 #endif
 
+static DWORD get_interface_index(const char *guid)
+{
+ULONG index;
+DWORD status;
+wchar_t wbuf[512];
+snwprintf(wbuf, sizeof(wbuf), L"\\device\\tcpip_%s", guid);
+wbuf[sizeof(wbuf) - 1] = 0;
+status = GetAdapterIndex (wbuf, &index);
+if (status != NO_ERROR) {
+return (DWORD)~0;
+} else {
+return index;
+

[Qemu-devel] [PATCH v7 RESEND] qga: Add support network interface statistics in guest-network-get-interfaces command

2017-09-12 Thread ZhiPeng Lu
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us to monitor
and analyze network traffic.

Signed-off-by: ZhiPeng Lu 

---
v1->v2:
 - correct some spelling mistake and add the stats data to the
   guest-network-get-interfaces command instead of adding a new command.
v2-v3:
 - optimize function implementation
v3->v4:
 - modify compile error
v4->v5:
 - rename some temporary variables and add str_trim_off function for
   calculating the space num in front of the string in guest_get_network_stats
v5->v6:
 - use g_strchug instead of str_trim_off implemented by myself
v6->v7:
 - add implementation for windows
---
 qga/commands-posix.c | 72 +++-
 qga/commands-win32.c | 48 +++
 qga/qapi-schema.json | 38 ++-
 3 files changed, 156 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index ab0c63d..da5dba0 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1643,6 +1643,65 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+static int guest_get_network_stats(const char *name,
+   GuestNetworkInterfaceStat *stats)
+{
+int name_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+name_len = strlen(name);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_dropped;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_dropped;
+char *trim_line;
+trim_line = g_strchug(line);
+if (trim_line[0] == '\0') {
+continue;
+}
+colon = strchr(trim_line, ':');
+if (!colon) {
+continue;
+}
+if (colon - name_len  == trim_line &&
+   strncmp(trim_line, name, name_len) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_dropped = rx_dropped;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_dropped = tx_dropped;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1659,6 +1718,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStat  *interface_stat = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1778,7 +1838,17 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 
 info->value->has_ip_addresses = true;
 
-
+if (!info->value->has_statistics) {
+interface_stat = g_malloc0(sizeof(*interface_stat));
+if (guest_get_network_stats(info->value->name,
+interface_stat) == -1) {
+info->value->has_statistics = false;
+g_free(interface_stat);
+} else {
+info->value->statistics = interface_stat;
+info->value->has_statistics = true;
+}
+}
 }
 
 freeifaddrs(ifap);
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 619dbd2..e891253 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -1152,6 +1152,42 @@ out:
 }
 #endif
 
+static DWORD get_interface_index(const char *guid)
+{
+ULONG index;
+DWORD status;
+wchar_t wbuf[512];
+snwprintf(wbuf, sizeof(wbuf), L"\\device\\tcpip_%s", guid);
+wbuf[sizeof(wbuf) - 1] = 0;
+status = GetAdapterIndex (wbuf, &index);
+if (status != NO_ERROR) {
+return (DWORD)~0;
+} else {
+return index;
+

[Qemu-devel] [PATCH RESEND v6] qga: Add support network interface statistics in guest-network-get-interfaces command

2017-05-12 Thread ZhiPeng Lu
we can get the network interface statistics inside a virtual machine by
guest-network-get-interfaces command. it is very useful for us to monitor
and analyze network traffic.

Signed-off-by: ZhiPeng Lu 
Signed-off-by: Daniel P. Berrange 
---
 qga/commands-posix.c | 80 +++-
 qga/qapi-schema.json | 38 -
 2 files changed, 116 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 915df9e..233b024 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1638,6 +1638,73 @@ guest_find_interface(GuestNetworkInterfaceList *head,
 return head;
 }
 
+
+static int str_trim_off(const char *s, int off, int lmt)
+{
+for (; off < lmt; ++off) {
+if (!isspace(s[off])) {
+break;
+}
+}
+return off;
+}
+
+static int guest_get_network_stats(const char *name,
+   GuestNetworkInterfaceStat *stats)
+{
+int name_len;
+char const *devinfo = "/proc/net/dev";
+FILE *fp;
+char *line = NULL, *colon;
+size_t n;
+fp = fopen(devinfo, "r");
+if (!fp) {
+return -1;
+}
+name_len = strlen(name);
+while (getline(&line, &n, fp) != -1) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_dropped;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_dropped;
+int trim_off;
+colon = strchr(line, ':');
+if (!colon) {
+continue;
+}
+trim_off = str_trim_off(line, 0, strlen(line));
+if (colon - name_len - trim_off == line &&
+   strncmp(line + trim_off, name, colon - line - trim_off) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+  &dummy, &dummy, &dummy, &dummy,
+  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+  &dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_dropped = rx_dropped;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_dropped = tx_dropped;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1654,6 +1721,7 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
 GuestNetworkInterfaceList *info;
 GuestIpAddressList **address_list = NULL, *address_item = NULL;
+GuestNetworkInterfaceStat  *interface_stat = NULL;
 char addr4[INET_ADDRSTRLEN];
 char addr6[INET6_ADDRSTRLEN];
 int sock;
@@ -1773,7 +1841,17 @@ GuestNetworkInterfaceList 
*qmp_guest_network_get_interfaces(Error **errp)
 
 info->value->has_ip_addresses = true;
 
-
+if (!info->value->has_statistics) {
+interface_stat = g_malloc0(sizeof(*interface_stat));
+if (guest_get_network_stats(info->value->name,
+interface_stat) == -1) {
+info->value->has_statistics = false;
+g_free(interface_stat);
+} else {
+info->value->statistics = interface_stat;
+info->value->has_statistics = true;
+}
+}
 }
 
 freeifaddrs(ifap);
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index a02dbf2..948219b 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -635,6 +635,38 @@
'prefix': 'int'} }
 
 ##
+# @GuestNetworkInterfaceStat:
+#
+# @rx-bytes: total bytes received
+#
+# @rx-packets: total packets received
+#
+# @rx-errs: bad packets received
+#
+# @rx-dropped: receiver dropped packets
+#
+# @tx-bytes: total bytes transmitted
+#
+# @tx-packets: total packets transmitted
+#
+# @tx-errs: packet transmit problems
+#
+# @tx-dropped: dropped packets transmitted
+#
+# Since: 2.10
+##
+{ 'struct': 'GuestNetworkInterfaceStat',
+  'data': {'rx-bytes': 'uint64',
+'rx-packets': 'uint64',
+'rx-errs': 'uint64',
+'rx-dropped': 'uint64',
+'tx-bytes': 'uint64&#x

[Qemu-devel] [PATCH] net: add print link status of nics in print_net_client function

2017-10-19 Thread ZhiPeng Lu
We can directly know the information of vm by executing "info network" command,
 including the link state of nics, without excuting other commands again.

Signed-off-by: ZhiPeng Lu 
Reviewed-by: Jiyun Fan 
---
 net/net.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/net.c b/net/net.c
index 39ef546..9e349cb 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1298,10 +1298,14 @@ void print_net_client(Monitor *mon, NetClientState *nc)
 {
 NetFilterState *nf;
 
-monitor_printf(mon, "%s: index=%d,type=%s,%s\n", nc->name,
+monitor_printf(mon, "%s: index=%d,type=%s,%s", nc->name,
nc->queue_index,
NetClientDriver_str(nc->info->type),
nc->info_str);
+if (nc->info->type == NET_CLIENT_DRIVER_NIC) {
+monitor_printf(mon, ",link status:%s", nc->link_down ? "down" : "up");
+}
+monitor_printf(mon, "\n");
 if (!QTAILQ_EMPTY(&nc->filters)) {
 monitor_printf(mon, "filters:\n");
 }
-- 
1.8.3.1




[Qemu-devel] [PATCH v2] net: add print link status of nic in print_net_client function

2017-11-03 Thread ZhiPeng Lu
We can directly know the information of vm by executing "info network" command,
 including the link state of nics, without executing other commands again.

Signed-off-by: ZhiPeng Lu 
Reviewed-by: Jiyun Fan 
Reviewed-by: Philippe Mathieu-Daudé 
---
v2: correct commit messages
---
 net/net.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/net.c b/net/net.c
index 39ef546..9e349cb 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1298,10 +1298,14 @@ void print_net_client(Monitor *mon, NetClientState *nc)
 {
 NetFilterState *nf;
 
-monitor_printf(mon, "%s: index=%d,type=%s,%s\n", nc->name,
+monitor_printf(mon, "%s: index=%d,type=%s,%s", nc->name,
nc->queue_index,
NetClientDriver_str(nc->info->type),
nc->info_str);
+if (nc->info->type == NET_CLIENT_DRIVER_NIC) {
+monitor_printf(mon, ",link status:%s", nc->link_down ? "down" : "up");
+}
+monitor_printf(mon, "\n");
 if (!QTAILQ_EMPTY(&nc->filters)) {
 monitor_printf(mon, "filters:\n");
 }
-- 
1.8.3.1




[Qemu-devel] [PATCH v2] qga: replace GetIfEntry

2017-11-03 Thread ZhiPeng Lu
The data obtained by GetIfEntry is 32 bits, and it may overflow. Thus using 
GetIfEntry2 instead of GetIfEntry.

Signed-off-by: ZhiPeng Lu 
---
 qga/commands-win32.c | 31 ++-
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 0322188..d096dc2 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -1173,20 +1173,25 @@ static int guest_get_network_stats(const char *name,
GuestNetworkInterfaceStat *stats)
 {
 DWORD if_index = 0;
-MIB_IFROW a_mid_ifrow;
-memset(&a_mid_ifrow, 0, sizeof(a_mid_ifrow));
+OSVERSIONINFO OSver;
 if_index = get_interface_index(name);
-a_mid_ifrow.dwIndex = if_index;
-if (NO_ERROR == GetIfEntry(&a_mid_ifrow)) {
-stats->rx_bytes = a_mid_ifrow.dwInOctets;
-stats->rx_packets = a_mid_ifrow.dwInUcastPkts;
-stats->rx_errs = a_mid_ifrow.dwInErrors;
-stats->rx_dropped = a_mid_ifrow.dwInDiscards;
-stats->tx_bytes = a_mid_ifrow.dwOutOctets;
-stats->tx_packets = a_mid_ifrow.dwOutUcastPkts;
-stats->tx_errs = a_mid_ifrow.dwOutErrors;
-stats->tx_dropped = a_mid_ifrow.dwOutDiscards;
-return 0;
+OSver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+GetVersionEx(&OSver);
+if (OSver.dwMajorVersion >= 6) {
+MIB_IF_ROW2 a_mid_ifrow;
+memset(&a_mid_ifrow, 0, sizeof(a_mid_ifrow));
+a_mid_ifrow.dwIndex = if_index;
+if (NO_ERROR == GetIfEntry2(&a_mid_ifrow)) {
+stats->rx_bytes = a_mid_ifrow.dwInOctets;
+stats->rx_packets = a_mid_ifrow.dwInUcastPkts;
+stats->rx_errs = a_mid_ifrow.dwInErrors;
+stats->rx_dropped = a_mid_ifrow.dwInDiscards;
+stats->tx_bytes = a_mid_ifrow.dwOutOctets;
+stats->tx_packets = a_mid_ifrow.dwOutUcastPkts;
+stats->tx_errs = a_mid_ifrow.dwOutErrors;
+stats->tx_dropped = a_mid_ifrow.dwOutDiscards;
+return 0;
+}
 }
 return -1;
 }
-- 
1.8.3.1




[Qemu-devel] [PATCH] vhost: skip RAM device memory sections

2017-04-07 Thread ZhiPeng Lu
A RAM device represents a mapping to a physical device, such as to a PCI
* MMIO BAR of an vfio-pci assigned device.
Vhost listens to this region,and increases the region's reference count
while passthrough?for?network adapters (Physical Function, PF or Virtual 
Function, VF).
After detaching   network adapters with  vhost backend dirver or vhost user 
dirver,
it unregister vhost listen function  by memory_listener_unregister.
After detaching the passthrough pf  or vf,
the RAM device region's reference by  vhost listener increated can not be 
released,
due to vhost listen function does not exist.So let's just skip RAM device 
memory.

Signed-off-by: ZhiPeng Lu 
---
 hw/virtio/vhost.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 613494d..c1ff98f 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -611,7 +611,8 @@ static void vhost_set_memory(MemoryListener *listener,
 static bool vhost_section(MemoryRegionSection *section)
 {
 return memory_region_is_ram(section->mr) &&
-!memory_region_is_rom(section->mr);
+!memory_region_is_rom(section->mr) &&
+!memory_region_is_skip_dump(section->mr);
 }
 
 static void vhost_begin(MemoryListener *listener)
-- 
1.8.3.1





[Qemu-devel] [PATCH] qemu-ga: add guest-network-get-interface-stat command

2017-04-19 Thread ZhiPeng Lu
we can get the  network card statistics inside  a virtual machine by 
guest-network-get-interface-stat command.
it is very userful for us to monitor and analyze network traff.

Signed-off-by: ZhiPeng Lu 
---
 qga/commands-posix.c | 166 ++-
 qga/commands-win32.c |   6 ++
 qga/qapi-schema.json |  34 +++
 3 files changed, 205 insertions(+), 1 deletion(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 915df9e..3166bf4 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -2357,6 +2357,163 @@ GuestMemoryBlockInfo 
*qmp_guest_get_memory_block_info(Error **errp)
 
 return info;
 }
+static int ga_get_netname(int bus, int dev, int func, char *netname,
+   int name_len)
+{
+int cnt = 0;
+int result = -1;
+
+FILE *pfilein = NULL;
+
+bool findnet = false;
+char *netpos = NULL;
+
+char netstr[32] = {0};
+char buffer[1024] = {0};
+
+if (NULL == netname) {
+return -1;
+}
+snprintf(netstr, 31, "%02x:%02x.%01x", bus, dev, func);
+g_debug("qga net pci is : %s ", netstr);
+
+pfilein = popen("ls -l /sys/class/net", "r");
+if (NULL == pfilein) {
+g_debug("failed to do shell command for [%s] getting net name", 
netstr);
+return -1;
+}
+
+while (fgets(buffer, 1023, pfilein) != NULL) {
+if (strstr(buffer, netstr)) {
+findnet = true;
+g_debug("find pci  [%s] net string: %s", netstr, buffer);
+break;
+}
+}
+
+result = ferror(pfilein);
+if (pclose(pfilein) || result) {
+g_debug("error happened while finding pci [%s] net string", netstr);
+return -1;
+}
+
+if (!findnet) {
+g_debug("didn't finding bdf [%s] block string", netstr);
+return -1;
+}
+
+netpos = strrchr(buffer, '/');
+if (NULL == netpos) {
+g_debug("can't get net name for [%s]", netstr);
+return -1;
+}
+
+netpos++;
+if (name_len < strlen(netpos)) {
+g_debug("net name buffer of [%s] is not enough", netstr);
+return -1;
+}
+
+cnt = 0;
+while (('\0' != *netpos) && ('\n' != *netpos)) {
+netname[cnt] = *netpos;
+cnt++;
+netpos++;
+}
+netname[cnt] = '\0';
+
+if ('\0' == netname[0]) {
+g_debug("net name for pci  [%s] is invalid", netstr);
+return -1;
+}
+
+g_debug("succeed to get pci [%s] actual net name: %s", netstr, netname);
+return 0;
+}
+
+
+static int ga_get_net_stats(const char *path,
+ GuestNetworkInterfaceStat *stats)
+{
+int path_len;
+FILE *fp;
+char line[256], *colon;
+
+fp = fopen("/proc/net/dev", "r");
+if (!fp) {
+slog("Could not open /proc/net/dev");
+return -1;
+}
+path_len = strlen(path);
+while (fgets(line, sizeof(line), fp)) {
+long long dummy;
+long long rx_bytes;
+long long rx_packets;
+long long rx_errs;
+long long rx_drop;
+long long tx_bytes;
+long long tx_packets;
+long long tx_errs;
+long long tx_drop;
+
+/* The line looks like:
+ *  *   "   eth0:..."
+ *   * Split it at the colon.
+ **/
+colon = strchr(line, ':');
+if (!colon) {
+continue;
+}
+*colon = '\0';
+if (colon - path_len >= line && strcmp(colon - path_len, path) == 0) {
+if (sscanf(colon + 1,
+"%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld 
%lld %lld %lld %lld",
+&rx_bytes, &rx_packets, &rx_errs, &rx_drop,
+&dummy, &dummy, &dummy, &dummy,
+&tx_bytes, &tx_packets, &tx_errs, &tx_drop,
+&dummy, &dummy, &dummy, &dummy) != 16) {
+continue;
+}
+stats->rx_bytes = rx_bytes;
+stats->rx_packets = rx_packets;
+stats->rx_errs = rx_errs;
+stats->rx_drop = rx_drop;
+stats->tx_bytes = tx_bytes;
+stats->tx_packets = tx_packets;
+stats->tx_errs = tx_errs;
+stats->tx_drop = tx_drop;
+fclose(fp);
+return 0;
+}
+}
+fclose(fp);
+
+g_debug("/proc/net/dev: Interface not found");
+return -1;
+}
+
+GuestNetworkInterfaceStatList *qmp_guest_network_get_interface_stat(int64_t 
bus,
+int64_t slot, int64_t function, const char *netname, Error **errp)
+{
+char guestnetname[14] = {0};
+GuestNetworkInterfaceStat *info = NUL