static virDomainNetDefPtr
virDomainNetDefParseXML(virCapsPtr caps,
xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
int flags ATTRIBUTE_UNUSED) {
virDomainNetDefPtr def;
xmlNodePtr cur;
virNWFilterHashTablePtr filterparams = NULL;
virVirtualPortProfileParams virtPort;
bool virtPortParsed = false;
+ xmlNodePtr oldnode = ctxt->node;
+ int ret;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
return NULL;
}
+ ctxt->node = node;
+
type = virXMLPropString(node, "type");
if (type != NULL) {
if ((int)(def->type = virDomainNetTypeFromString(type)) < 0) {
}
}
+ ret = virXPathULong("string(./tune/sndbuf)", ctxt, &def->tune.sndbuf);
+ if (ret >= 0) {
+ def->tune.sndbuf_specified = true;
+ } else if (ret == -2) {
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+ _("sndbuf must be a positive integer"));
+ goto error;
+ }
+
cleanup:
+ ctxt->node = oldnode;
VIR_FREE(macaddr);
VIR_FREE(network);
VIR_FREE(address);
{
xmlDocPtr xml;
xmlNodePtr node;
+ xmlXPathContextPtr ctxt = NULL;
virDomainDeviceDefPtr dev = NULL;
if (!(xml = xmlReadDoc(BAD_CAST xmlStr, "device.xml", NULL,
goto error;
}
+ ctxt = xmlXPathNewContext(xml);
+ if (ctxt == NULL) {
+ virReportOOMError();
+ goto error;
+ }
+ ctxt->node = node;
+
if (VIR_ALLOC(dev) < 0) {
virReportOOMError();
goto error;
goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "interface")) {
dev->type = VIR_DOMAIN_DEVICE_NET;
- if (!(dev->data.net = virDomainNetDefParseXML(caps, node, flags)))
+ if (!(dev->data.net = virDomainNetDefParseXML(caps, node, ctxt, flags)))
goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "input")) {
dev->type = VIR_DOMAIN_DEVICE_INPUT;
}
xmlFreeDoc(xml);
-
+ xmlXPathFreeContext(ctxt);
return dev;
error:
xmlFreeDoc(xml);
+ xmlXPathFreeContext(ctxt);
VIR_FREE(dev);
return NULL;
}
for (i = 0 ; i < n ; i++) {
virDomainNetDefPtr net = virDomainNetDefParseXML(caps,
nodes[i],
+ ctxt,
flags);
if (!net)
goto error;
VIR_FREE(attrs);
}
+ if (def->tune.sndbuf_specified) {
+ virBufferAddLit(buf, " <tune>\n");
+ virBufferVSprintf(buf, " <sndbuf>%lu</sndbuf>\n", def->tune.sndbuf);
+ virBufferAddLit(buf, " </tune>\n");
+ }
+
if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
return -1;
const char *tapfd,
const char *vhostfd)
{
+ bool is_tap = false;
virBuffer buf = VIR_BUFFER_INITIALIZER;
switch (net->type) {
virBufferAddLit(&buf, "tap");
virBufferVSprintf(&buf, "%cfd=%s", type_sep, tapfd);
type_sep = ',';
+ is_tap = true;
break;
case VIR_DOMAIN_NET_TYPE_ETHERNET:
net->data.ethernet.script);
type_sep = ',';
}
+ is_tap = true;
break;
case VIR_DOMAIN_NET_TYPE_CLIENT:
type_sep, net->info.alias);
}
- if (vhostfd && *vhostfd) {
- virBufferVSprintf(&buf, ",vhost=on,vhostfd=%s", vhostfd);
+ if (is_tap) {
+ if (vhostfd && *vhostfd)
+ virBufferVSprintf(&buf, ",vhost=on,vhostfd=%s", vhostfd);
+ if (net->tune.sndbuf_specified)
+ virBufferVSprintf(&buf, ",sndbuf=%lu", net->tune.sndbuf);
}
if (virBufferError(&buf)) {
} else if (STREQ(keywords[i], "off")) {
def->backend = VIR_DOMAIN_NET_BACKEND_TYPE_QEMU;
}
+ } else if (STREQ(keywords[i], "sndbuf") && values[i]) {
+ if (virStrToLong_ul(values[i], NULL, 10, &def->tune.sndbuf) < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse sndbuf size in '%s'"), val);
+ virDomainNetDefFree(def);
+ def = NULL;
+ goto cleanup;
+ }
+ def->tune.sndbuf_specified = true;
}
}