[libvirt] [PATCH v3 1/4] vz: add net dev statistiscs

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Fri Jun 26 11:24:12 UTC 2015


From: Nikolay Shirokovskiy <nshirokovskiy at parallels.com>

Populate counters SDK currenly supports:
 rx_bytes
 rx_packets
 tx_bytes
 tx_packets

Comments.

Use vzDomObjFromDomainRef/virDomainObjEndAPI pair to get domain
object as we use prlsdkGetStatsParam that can release domain
object lock and thus we need a reference in case domain
is deleated meanwhile.

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy at virtuozzo.com>
---
 src/vz/vz_driver.c |   17 ++++++++++
 src/vz/vz_sdk.c    |   91 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/vz/vz_sdk.h    |    2 +
 3 files changed, 109 insertions(+), 1 deletions(-)

diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index d9ddd4f..5c503c6 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -1337,6 +1337,22 @@ vzDomainBlockStatsFlags(virDomainPtr domain,
     return ret;
 }
 
+static int
+vzDomainInterfaceStats(virDomainPtr domain,
+                         const char *path,
+                         virDomainInterfaceStatsPtr stats)
+{
+    virDomainObjPtr dom = NULL;
+    int ret;
+
+    if (!(dom = vzDomObjFromDomainRef(domain)))
+        return -1;
+
+    ret = prlsdkGetNetStats(dom, path, stats);
+    virDomainObjEndAPI(&dom);
+
+    return ret;
+}
 
 static virHypervisorDriver vzDriver = {
     .name = "vz",
@@ -1389,6 +1405,7 @@ static virHypervisorDriver vzDriver = {
     .domainGetMaxMemory = vzDomainGetMaxMemory, /* 1.2.15 */
     .domainBlockStats = vzDomainBlockStats, /* 1.3.0 */
     .domainBlockStatsFlags = vzDomainBlockStatsFlags, /* 1.3.0 */
+    .domainInterfaceStats = vzDomainInterfaceStats, /* 1.3.0 */
 };
 
 static virConnectDriver vzConnectDriver = {
diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
index 388ea19..6401096 100644
--- a/src/vz/vz_sdk.c
+++ b/src/vz/vz_sdk.c
@@ -3697,7 +3697,7 @@ prlsdkExtractStatsParam(PRL_HANDLE sdkstats, const char *name, long long *val)
 
 #define PARALLELS_STATISTICS_TIMEOUT (60 * 1000)
 
-static int
+int
 prlsdkGetStatsParam(virDomainObjPtr dom, const char *name, long long *val)
 {
     vzDomObjPtr privdom = dom->privateData;
@@ -3793,3 +3793,92 @@ prlsdkGetBlockStats(virDomainObjPtr dom, virDomainDiskDefPtr disk, virDomainBloc
     VIR_FREE(name);
     return ret;
 }
+
+static PRL_HANDLE
+prlsdkFindNetByPath(virDomainObjPtr dom, const char *path)
+{
+    PRL_UINT32 count = 0;
+    vzDomObjPtr privdom = dom->privateData;
+    PRL_UINT32 buflen = 0;
+    PRL_RESULT pret;
+    size_t i;
+    char *name = NULL;
+    PRL_HANDLE net = PRL_INVALID_HANDLE;
+
+    pret = PrlVmCfg_GetNetAdaptersCount(privdom->sdkdom, &count);
+    prlsdkCheckRetGoto(pret, error);
+
+    for (i = 0; i < count; ++i) {
+        pret = PrlVmCfg_GetNetAdapter(privdom->sdkdom, i, &net);
+        prlsdkCheckRetGoto(pret, error);
+
+        pret = PrlVmDevNet_GetHostInterfaceName(net, NULL, &buflen);
+        prlsdkCheckRetGoto(pret, error);
+
+        if (VIR_ALLOC_N(name, buflen) < 0)
+            goto error;
+
+        pret = PrlVmDevNet_GetHostInterfaceName(net, name, &buflen);
+        prlsdkCheckRetGoto(pret, error);
+
+        if (STREQ(name, path))
+            break;
+
+        VIR_FREE(name);
+        PrlHandle_Free(net);
+        net = PRL_INVALID_HANDLE;
+    }
+
+    if (net == PRL_INVALID_HANDLE)
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("invalid path, '%s' is not a known interface"), path);
+    return net;
+
+ error:
+    VIR_FREE(name);
+    PrlHandle_Free(net);
+    return PRL_INVALID_HANDLE;
+}
+
+int
+prlsdkGetNetStats(virDomainObjPtr dom, const char *path,
+                  virDomainInterfaceStatsPtr stats)
+{
+    int ret = -1;
+    PRL_UINT32 net_index = -1;
+    char *name = NULL;
+    PRL_RESULT pret;
+    PRL_HANDLE net = PRL_INVALID_HANDLE;
+
+    net = prlsdkFindNetByPath(dom, path);
+    if (net == PRL_INVALID_HANDLE)
+       goto cleanup;
+
+    pret = PrlVmDev_GetIndex(net, &net_index);
+    prlsdkCheckRetGoto(pret, cleanup);
+
+#define PRLSDK_GET_NET_COUNTER(VAL, NAME)                           \
+    if (virAsprintf(&name, "net.nic%d.%s", net_index, NAME) < 0)    \
+        goto cleanup;                                               \
+    if (prlsdkGetStatsParam(dom, name, &stats->VAL) < 0)            \
+        goto cleanup;                                               \
+    VIR_FREE(name);
+
+    PRLSDK_GET_NET_COUNTER(rx_bytes, "bytes_in")
+    PRLSDK_GET_NET_COUNTER(rx_packets, "pkts_in")
+    PRLSDK_GET_NET_COUNTER(tx_bytes, "bytes_out")
+    PRLSDK_GET_NET_COUNTER(tx_packets, "pkts_out")
+    stats->rx_errs = -1;
+    stats->rx_drop = -1;
+    stats->tx_errs = -1;
+    stats->tx_drop = -1;
+
+#undef PRLSDK_GET_NET_COUNTER
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(name);
+    PrlHandle_Free(net);
+
+    return ret;
+}
diff --git a/src/vz/vz_sdk.h b/src/vz/vz_sdk.h
index 80ff69a..53fe21f 100644
--- a/src/vz/vz_sdk.h
+++ b/src/vz/vz_sdk.h
@@ -70,3 +70,5 @@ int
 prlsdkAttachNet(virDomainObjPtr dom, vzConnPtr privconn, virDomainNetDefPtr net);
 int
 prlsdkDetachNet(virDomainObjPtr dom, vzConnPtr privconn, virDomainNetDefPtr net);
+int
+prlsdkGetNetStats(virDomainObjPtr dom, const char *path, virDomainInterfaceStatsPtr stats);
-- 
1.7.1




More information about the libvir-list mailing list