---
src/conf/domain_conf.c | 3 +
src/conf/network_conf.c | 3 +
src/libvirt_private.syms | 3 +
src/util/network.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/network.h | 7 ++
5 files changed, 169 insertions(+), 0 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b7c88c8..0dfcd5c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8687,6 +8687,9 @@ virDomainNetDefFormat(virBufferPtr buf,
virBufferAddLit(buf, " </tune>\n");
}
+ if (virBandwidrhDefFormat(buf, &def->bandwidth, " ") < 0)
+ return -1;
+
if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
return -1;
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index ef5d31e..02b4cca 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -886,6 +886,9 @@ char *virNetworkDefFormat(const virNetworkDefPtr def)
if (def->domain)
virBufferAsprintf(&buf, " <domain name='%s'/>\n",
def->domain);
+ if (virBandwidrhDefFormat(&buf, &def->bandwidth, " ") < 0)
+ goto error;
+
for (ii = 0; ii < def->nips; ii++) {
if (virNetworkIpDefFormat(&buf, &def->ips[ii]) < 0)
goto error;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a2c8470..6640cfb 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -681,7 +681,10 @@ nlComm;
# network.h
+virBandwidrhDefFormat;
virBandwidthDefParseNode;
+virBpsToRate;
+virBtoSize;
virSocketAddrBroadcast;
virSocketAddrBroadcastByPrefix;
virSocketAddrIsNetmask;
diff --git a/src/util/network.c b/src/util/network.c
index 476ecde..b24f977 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -877,3 +877,156 @@ virBandwidthDefParseNode(xmlNodePtr node, virBandwidthPtr def)
cleanup:
return ret;
}
+
+/**
+ * virBpsToRate:
+ * @buf: output
+ * @rate: input
+ *
+ * Format rate, take bps as input. Do pretty formating.
+ * Caller MUST free @buf after use.
+ *
+ * Return 0 on success, -1 otherwise.
+ */
+int virBpsToRate(char **buf, unsigned long rate) {
+ int ret = -1;
+ double tmp = (double)rate*8;
+
+ if (tmp >= 1000.*1000.*1000.) {
+ if (virAsprintf(buf, "%.0fmbit", tmp/1000./1000.) < 0)
+ goto cleanup;
+ } else if (tmp >= 1000.*1000.) {
+ if (virAsprintf(buf, "%.0fkbit", tmp/1000.) < 0)
+ goto cleanup;
+ } else {
+ if (virAsprintf(buf, "%.0fbit", tmp) < 0)
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ return ret;
+}
+
+/**
+ * virBtoSize:
+ * @buf: output
+ * @size: input
+ *
+ * Format size, take size in bytes, produce prettier format.
+ * Caller MUST free @buf after use.
+ *
+ * Return 0 on success, -1 otherwise.
+ */
+int virBtoSize(char **buf, unsigned long size) {
+ int ret = -1;
+ double tmp = (double)size;
+
+ if (size >= 1024*1024 &&
+ fabs(1024*1024 * rint(tmp/(1024*1024)) - size) < 1024) {
+ if (virAsprintf(buf, "%gmb", rint(tmp/(1024*1024))) < 0)
+ goto cleanup;
+ } else if (size >= 1024 &&
+ fabs(1024*rint(tmp/1024) - size) < 16) {
+ if (virAsprintf(buf, "%gkb", rint(tmp/1024)) < 0)
+ goto cleanup;
+ } else {
+ if (virAsprintf(buf, "%lub", size) < 0)
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ return ret;
+}
+
+static int
+virBandwidthChildDefFormat(virBufferPtr buf,
+ virRatePtr def,
+ const char *elem_name)
+{
+ int ret = -1;
+ char *tmp = NULL;
+
+ if (!buf || !def || !elem_name)
+ return -1;
+
+ if (def->average) {
+ if (virBpsToRate(&tmp, def->average) < 0)
+ goto cleanup;
+ virBufferAsprintf(buf, "<%s average='%s'", elem_name, tmp);
+ VIR_FREE(tmp);
+
+ if (def->peak) {
+ if (virBpsToRate(&tmp, def->peak) < 0)
+ goto cleanup;
+ virBufferAsprintf(buf, " peak='%s'", tmp);
+ VIR_FREE(tmp);
+ }
+
+ if (def->burst) {
+ if (virBtoSize(&tmp, def->burst))
+ goto cleanup;
+ virBufferAsprintf(buf, " burst='%s'", tmp);
+ VIR_FREE(tmp);
+ }
+ virBufferAddLit(buf, "/>\n");
+ }
+
+ ret = 0;
+
+cleanup:
+ return ret;
+}
+
+/**
+ * virBandwidrhDefFormat:
+ * @buf: Buffer to print to
+ * @def: Data source
+ * @indent: prepend all lines printed with this
+ *
+ * Formats bandwidth and prepend each line with @indent.
+ * Passing NULL to @indent is equivalent passing "".
+ *
+ * Returns 0 on success, else -1.
+ */
+int
+virBandwidrhDefFormat(virBufferPtr buf,
+ virBandwidthPtr def,
+ const char *indent)
+{
+ int ret = -1;
+
+ if (!buf || !def)
+ goto cleanup;
+
+ if (!indent)
+ indent = "";
+
+ if (!def->in.average && !def->out.average) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ virBufferAsprintf(buf, "%s<bandwidth>\n", indent);
+ if (def->in.average) {
+ virBufferAsprintf(buf, "%s ", indent);
+ if (virBandwidthChildDefFormat(buf, &def->in, "inbound") <
0)
+ goto cleanup;
+ }
+
+ if (def->out.average) {
+ virBufferAsprintf(buf, "%s ", indent);
+ if (virBandwidthChildDefFormat(buf, &def->out, "outbound") <
0)
+ goto cleanup;
+ }
+
+ virBufferAsprintf(buf, "%s</bandwidth>\n", indent);
+
+ ret = 0;
+
+cleanup:
+ return ret;
+}
diff --git a/src/util/network.h b/src/util/network.h
index 28a6402..f8cdc55 100644
--- a/src/util/network.h
+++ b/src/util/network.h
@@ -21,6 +21,7 @@
# include <netdb.h>
# include <netinet/in.h>
# include "xml.h"
+# include "buf.h"
typedef struct {
union {
@@ -108,4 +109,10 @@ int virSocketAddrPrefixToNetmask(unsigned int prefix,
int family);
int virBandwidthDefParseNode(xmlNodePtr node, virBandwidthPtr def);
+int virBandwidrhDefFormat(virBufferPtr buf,
+ virBandwidthPtr def,
+ const char *indent);
+
+int virBpsToRate(char **buf, unsigned long rate);
+int virBtoSize(char **buf, unsigned long size);
#endif /* __VIR_NETWORK_H__ */
--
1.7.5.rc3