--- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list