From 1dd34bbb4b70e163f1b303f43b7c3507d2db086b Mon Sep 17 00:00:00 2001 From: Jim Fehlig Date: Mon, 4 Jan 2016 17:46:31 -0700 Subject: [PATCH] xenconfig: support vif bandwidth in sexpr parser and formatter The xen sexpr config format has long supported specifying vif rate limiting, e.g. (device (vif (mac '00:16:3e:1b:b1:47') (rate '10240KB/s') ... ) ) Add support for mapping rate to and from in the xenconfig sexpr parser and formatter. rate is mapped to the required 'average' attribute of the element, e.g. ... Also add unit tests to check the conversion logic. This patch benefits both the old xen driver and the libxl driver. Both drivers gain support for vif bandwidth when converting to/from domXML and xen-sxpr. In addition, the old xen driver will now be able to handle vif 'rate' setting when communicating with xend. --- src/libvirt_xenconfig.syms | 1 + src/xenconfig/xen_sxpr.c | 74 +++++++++++++++++++ src/xenconfig/xen_sxpr.h | 2 + tests/sexpr2xmldata/sexpr2xml-vif-rate.sexpr | 11 +++ tests/sexpr2xmldata/sexpr2xml-vif-rate.xml | 51 +++++++++++++ tests/sexpr2xmltest.c | 2 + .../xml2sexprdata/xml2sexpr-fv-net-rate.sexpr | 10 +++ tests/xml2sexprdata/xml2sexpr-fv-net-rate.xml | 34 +++++++++ tests/xml2sexprtest.c | 1 + 9 files changed, 186 insertions(+) create mode 100644 tests/sexpr2xmldata/sexpr2xml-vif-rate.sexpr create mode 100644 tests/sexpr2xmldata/sexpr2xml-vif-rate.xml create mode 100644 tests/xml2sexprdata/xml2sexpr-fv-net-rate.sexpr create mode 100644 tests/xml2sexprdata/xml2sexpr-fv-net-rate.xml diff --git a/src/libvirt_xenconfig.syms b/src/libvirt_xenconfig.syms index 6541685fe5..b69f2ab493 100644 --- a/src/libvirt_xenconfig.syms +++ b/src/libvirt_xenconfig.syms @@ -15,6 +15,7 @@ xenParseSxpr; xenParseSxprChar; xenParseSxprSound; xenParseSxprString; +xenParseSxprVifRate; # xenconfig/xen_xm.h xenFormatXM; diff --git a/src/xenconfig/xen_sxpr.c b/src/xenconfig/xen_sxpr.c index d7b700d647..a7a622f789 100644 --- a/src/xenconfig/xen_sxpr.c +++ b/src/xenconfig/xen_sxpr.c @@ -26,6 +26,8 @@ #include +#include + #include "internal.h" #include "virerror.h" #include "virconf.h" @@ -315,6 +317,56 @@ xenParseSxprChar(const char *value, } +static const char *vif_bytes_per_sec_re = "^[0-9]+[GMK]?[Bb]/s$"; + +int +xenParseSxprVifRate(const char *rate, unsigned long long *kbytes_per_sec) +{ + char *trate = NULL; + char *p; + regex_t rec; + char *suffix; + unsigned long long tmp; + int ret = -1; + + if (VIR_STRDUP(trate, rate) < 0) + return -1; + + p = strchr(trate, '@'); + if (p != NULL) + *p = 0; + + regcomp(&rec, vif_bytes_per_sec_re, REG_EXTENDED|REG_NOSUB); + if (regexec(&rec, trate, 0, NULL, 0)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid rate '%s' specified"), rate); + goto cleanup; + } + + if (virStrToLong_ull(rate, &suffix, 10, &tmp)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to parse rate '%s'"), rate); + goto cleanup; + } + + if (*suffix == 'G') + tmp *= 1024 * 1024; + else if (*suffix == 'M') + tmp *= 1024; + + if (*suffix == 'b' || *(suffix + 1) == 'b') + tmp /= 8; + + *kbytes_per_sec = tmp; + ret = 0; + + cleanup: + regfree(&rec); + VIR_FREE(trate); + return ret; +} + + /** * xenParseSxprDisks: * @def: the domain config @@ -594,6 +646,25 @@ xenParseSxprNets(virDomainDefPtr def, VIR_STRDUP(net->model, "netfront") < 0) goto cleanup; + tmp = sexpr_node(node, "device/vif/rate"); + if (tmp) { + virNetDevBandwidthPtr bandwidth; + unsigned long long kbytes_per_sec; + + if (xenParseSxprVifRate(tmp, &kbytes_per_sec) < 0) + goto cleanup; + + if (VIR_ALLOC(bandwidth) < 0) + goto cleanup; + if (VIR_ALLOC(bandwidth->out) < 0) { + VIR_FREE(bandwidth); + goto cleanup; + } + + bandwidth->out->average = kbytes_per_sec; + net->bandwidth = bandwidth; + } + if (VIR_APPEND_ELEMENT(def->nets, def->nnets, net) < 0) goto cleanup; @@ -1783,6 +1854,9 @@ xenFormatSxprNet(virConnectPtr conn, virBufferAsprintf(buf, "(mac '%s')", virMacAddrFormat(&def->mac, macaddr)); + if (def->bandwidth && def->bandwidth->out && def->bandwidth->out->average) + virBufferAsprintf(buf, "(rate '%lluKB/s')", def->bandwidth->out->average); + switch (def->type) { case VIR_DOMAIN_NET_TYPE_BRIDGE: virBufferEscapeSexpr(buf, "(bridge '%s')", def->data.bridge.brname); diff --git a/src/xenconfig/xen_sxpr.h b/src/xenconfig/xen_sxpr.h index e925208b5d..cb8c89ef9a 100644 --- a/src/xenconfig/xen_sxpr.h +++ b/src/xenconfig/xen_sxpr.h @@ -53,6 +53,8 @@ int xenParseSxprSound(virDomainDefPtr def, const char *str); virDomainChrDefPtr xenParseSxprChar(const char *value, const char *tty); +int xenParseSxprVifRate(const char *rate, unsigned long long *kbytes_per_sec); + int xenFormatSxprDisk(virDomainDiskDefPtr def, virBufferPtr buf, int hvm, int isAttach); diff --git a/tests/sexpr2xmldata/sexpr2xml-vif-rate.sexpr b/tests/sexpr2xmldata/sexpr2xml-vif-rate.sexpr new file mode 100644 index 0000000000..c3ed8e8b9d --- /dev/null +++ b/tests/sexpr2xmldata/sexpr2xml-vif-rate.sexpr @@ -0,0 +1,11 @@ +(domain (domid 3)(name 'fvtest')(memory 400)(maxmem 400)(vcpus 1)\ +(uuid 'b5d70dd275cdaca517769660b059d8bc')(on_poweroff 'destroy')\ +(on_reboot 'restart')(on_crash 'restart')\ +(image (hvm (kernel '/usr/lib/xen/boot/hvmloader')\ +(device_model '/usr/lib64/xen/bin/qemu-dm')(boot c)\ +(acpi 1)(vnc 1)(keymap ja)))(device (vbd (dev 'ioemu:hda')\ +(uname 'file:/root/foo.img')(mode 'w')))\ +(device (vbd (dev 'hdc:cdrom')\ +(uname 'file:/root/boot.iso')(mode 'r')))\ +(device (vif (mac '00:16:3e:1b:b1:47')(bridge 'xenbr0')\ +(script 'vif-bridge')(type 'netfront')(rate '10240KB/s')))) diff --git a/tests/sexpr2xmldata/sexpr2xml-vif-rate.xml b/tests/sexpr2xmldata/sexpr2xml-vif-rate.xml new file mode 100644 index 0000000000..0531817d25 --- /dev/null +++ b/tests/sexpr2xmldata/sexpr2xml-vif-rate.xml @@ -0,0 +1,51 @@ + + fvtest + b5d70dd2-75cd-aca5-1776-9660b059d8bc + 409600 + 409600 + 1 + + hvm + /usr/lib/xen/boot/hvmloader + + + + + + + destroy + restart + restart + + /usr/lib64/xen/bin/qemu-dm + + + + + +
+ + + + + + + +
+ + + + + + + +