static int testVirNetDevBandwidthSet(const void *data) { int ret = -1; const struct testSetStruct *info = data; const char *iface = info->iface; virNetDevBandwidthPtr band = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; char *actual_cmd = NULL; PARSE(info->band, band); if (!iface) iface = "eth0"; virCommandSetDryRun(&buf, NULL, NULL); if (virNetDevBandwidthSet(iface, band, info->hierarchical_class) < 0) goto cleanup; if (!(actual_cmd = virBufferContentAndReset(&buf))) { int err = virBufferError(&buf); if (err) { fprintf(stderr, "buffer's in error state: %d", err); goto cleanup; } /* This is interesting, no command has been executed. * Maybe that's expected, actually. */ } if (STRNEQ_NULLABLE(info->exp_cmd, actual_cmd)) { virTestDifference(stderr, NULLSTR(info->exp_cmd), NULLSTR(actual_cmd)); goto cleanup; } ret = 0; cleanup: virCommandSetDryRun(NULL, NULL, NULL); virNetDevBandwidthFree(band); virBufferFreeAndReset(&buf); VIR_FREE(actual_cmd); return ret; }
/* * virNetDevBandwidthCopy: * @dest: destination * @src: source (may be NULL) * * Returns -1 on OOM error (which gets reported), * 0 otherwise. */ int virNetDevBandwidthCopy(virNetDevBandwidthPtr *dest, const virNetDevBandwidthPtr src) { int ret = -1; *dest = NULL; if (!src) { /* nothing to be copied */ return 0; } if (VIR_ALLOC(*dest) < 0) { virReportOOMError(); goto cleanup; } if (src->in) { if (VIR_ALLOC((*dest)->in) < 0) { virReportOOMError(); goto cleanup; } memcpy((*dest)->in, src->in, sizeof(*src->in)); } if (src->out) { if (VIR_ALLOC((*dest)->out) < 0) { virReportOOMError(); VIR_FREE((*dest)->in); goto cleanup; } memcpy((*dest)->out, src->out, sizeof(*src->out)); } ret = 0; cleanup: if (ret < 0) { virNetDevBandwidthFree(*dest); *dest = NULL; } return ret; }
/** * virNetDevBandwidthParse: * @bandwidth: parsed bandwidth * @node: XML node * @allowFloor: whether "floor" setting is supported * * Parse bandwidth XML and return pointer to structure. * The @allowFloor attribute indicates whether the caller * is able to support use of the "floor" setting. * * Returns !NULL on success, NULL on error. */ int virNetDevBandwidthParse(virNetDevBandwidthPtr *bandwidth, xmlNodePtr node, bool allowFloor) { int ret = -1; virNetDevBandwidthPtr def = NULL; xmlNodePtr cur; xmlNodePtr in = NULL, out = NULL; if (VIR_ALLOC(def) < 0) return ret; if (!node || !virXMLNodeNameEqual(node, "bandwidth")) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("invalid argument supplied")); goto cleanup; } cur = node->children; while (cur) { if (cur->type == XML_ELEMENT_NODE) { if (virXMLNodeNameEqual(cur, "inbound")) { if (in) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("Only one child <inbound> " "element allowed")); goto cleanup; } in = cur; } else if (virXMLNodeNameEqual(cur, "outbound")) { if (out) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("Only one child <outbound> " "element allowed")); goto cleanup; } out = cur; } /* Silently ignore unknown elements */ } cur = cur->next; } if (in) { if (VIR_ALLOC(def->in) < 0) goto cleanup; if (virNetDevBandwidthParseRate(in, def->in) < 0) { /* helper reported error for us */ goto cleanup; } if (def->in->floor && !allowFloor) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("floor attribute is not supported for this config")); goto cleanup; } } if (out) { if (VIR_ALLOC(def->out) < 0) goto cleanup; if (virNetDevBandwidthParseRate(out, def->out) < 0) { /* helper reported error for us */ goto cleanup; } if (def->out->floor) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("'floor' attribute allowed " "only in <inbound> element")); goto cleanup; } } if (!def->in && !def->out) VIR_FREE(def); *bandwidth = def; def = NULL; ret = 0; cleanup: virNetDevBandwidthFree(def); return ret; }
/** * virNetDevBandwidthParse: * @node: XML node * @net_type: one of virDomainNetType * * Parse bandwidth XML and return pointer to structure. * @net_type tell to which type will/is interface connected to. * Pass -1 if this is not called on interface. * * Returns !NULL on success, NULL on error. */ virNetDevBandwidthPtr virNetDevBandwidthParse(xmlNodePtr node, int net_type) { virNetDevBandwidthPtr def = NULL; xmlNodePtr cur; xmlNodePtr in = NULL, out = NULL; if (VIR_ALLOC(def) < 0) return NULL; if (!node || !xmlStrEqual(node->name, BAD_CAST "bandwidth")) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("invalid argument supplied")); goto error; } cur = node->children; while (cur) { if (cur->type == XML_ELEMENT_NODE) { if (xmlStrEqual(cur->name, BAD_CAST "inbound")) { if (in) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("Only one child <inbound> " "element allowed")); goto error; } in = cur; } else if (xmlStrEqual(cur->name, BAD_CAST "outbound")) { if (out) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("Only one child <outbound> " "element allowed")); goto error; } out = cur; } /* Silently ignore unknown elements */ } cur = cur->next; } if (in) { if (VIR_ALLOC(def->in) < 0) goto error; if (virNetDevBandwidthParseRate(in, def->in) < 0) { /* helper reported error for us */ goto error; } if (def->in->floor && net_type != VIR_DOMAIN_NET_TYPE_NETWORK) { if (net_type == -1) { /* 'floor' on network isn't supported */ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("floor attribute isn't supported for " "network's bandwidth yet")); } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("floor attribute is supported only for " "interfaces of type network")); } goto error; } } if (out) { if (VIR_ALLOC(def->out) < 0) goto error; if (virNetDevBandwidthParseRate(out, def->out) < 0) { /* helper reported error for us */ goto error; } if (def->out->floor) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("'floor' attribute allowed " "only in <inbound> element")); goto error; } } return def; error: virNetDevBandwidthFree(def); return NULL; }