actualBandwidth = virDomainNetGetActualBandwidth(net);
if (actualBandwidth) {
if (virNetDevSupportsBandwidth(actualType)) {
- if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false,
- !virDomainNetTypeSharesHostView(net)) < 0)
+ unsigned int flags = 0;
+
+ if (!virDomainNetTypeSharesHostView(net))
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, flags) < 0)
goto cleanup;
} else {
VIR_WARN("setting bandwidth on interfaces of "
actualBandwidth = virDomainNetGetActualBandwidth(net);
if (actualBandwidth) {
if (virNetDevSupportsBandwidth(type)) {
- if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false,
- !virDomainNetTypeSharesHostView(net)) < 0)
+ unsigned int flags = 0;
+
+ if (!virDomainNetTypeSharesHostView(net))
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, flags) < 0)
goto cleanup;
} else {
VIR_WARN("setting bandwidth on interfaces of "
}
}
- if (virNetDevBandwidthSet(def->bridge, def->bandwidth, true, true) < 0)
+ if (virNetDevBandwidthSet(def->bridge, def->bandwidth,
+ VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS
+ | VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED) < 0) {
goto error;
+ }
return 0;
* type BRIDGE, is started. On failure, undo anything you've done,
* and return -1. On success return 0.
*/
- if (virNetDevBandwidthSet(def->bridge, def->bandwidth, true, true) < 0)
+ if (virNetDevBandwidthSet(def->bridge, def->bandwidth,
+ VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS
+ | VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED) < 0) {
goto error;
+ }
if (networkStartHandleMACTableManagerMode(obj) < 0)
goto error;
def->uuid,
!virDomainNetTypeSharesHostView(net)) < 0)
goto cleanup;
- } else if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false,
- !virDomainNetTypeSharesHostView(net)) < 0) {
- goto cleanup;
+ } else {
+ unsigned int flags = 0;
+
+ if (!virDomainNetTypeSharesHostView(net))
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, flags) < 0)
+ goto cleanup;
}
} else {
VIR_WARN("setting bandwidth on interfaces of "
virErrorRestore(&orig_err);
goto endjob;
}
- } else if (virNetDevBandwidthSet(net->ifname, newBandwidth, false,
- !virDomainNetTypeSharesHostView(net)) < 0) {
- virErrorPtr orig_err;
-
- virErrorPreserveLast(&orig_err);
- ignore_value(virNetDevBandwidthSet(net->ifname,
- net->bandwidth,
- false,
- !virDomainNetTypeSharesHostView(net)));
- if (net->bandwidth) {
- ignore_value(virDomainNetBandwidthUpdate(net,
- net->bandwidth));
+ } else {
+ unsigned int bwflags = 0;
+
+ if (!virDomainNetTypeSharesHostView(net))
+ bwflags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (virNetDevBandwidthSet(net->ifname, newBandwidth, bwflags) < 0) {
+ virErrorPtr orig_err;
+
+ virErrorPreserveLast(&orig_err);
+ ignore_value(virNetDevBandwidthSet(net->ifname, net->bandwidth, bwflags));
+ if (net->bandwidth)
+ ignore_value(virDomainNetBandwidthUpdate(net, net->bandwidth));
+ virErrorRestore(&orig_err);
+ goto endjob;
}
- virErrorRestore(&orig_err);
- goto endjob;
}
/* If the old bandwidth was cleared out, restore qdisc. */
vm->def->uuid,
!virDomainNetTypeSharesHostView(net)) < 0)
goto cleanup;
- } else if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false,
- !virDomainNetTypeSharesHostView(net)) < 0) {
- goto cleanup;
+ } else {
+ int flags = 0;
+
+ if (!virDomainNetTypeSharesHostView(net))
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, flags) < 0)
+ goto cleanup;
}
} else {
VIR_WARN("setting bandwidth on interfaces of "
vm->def->uuid,
!virDomainNetTypeSharesHostView(newdev)) < 0)
goto cleanup;
- } else if (virNetDevBandwidthSet(newdev->ifname, newb, false,
- !virDomainNetTypeSharesHostView(newdev)) < 0) {
- goto cleanup;
+ } else {
+ int flags = 0;
+
+ if (!virDomainNetTypeSharesHostView(newdev))
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (virNetDevBandwidthSet(newdev->ifname, newb, flags) < 0)
+ goto cleanup;
}
} else {
if (virDomainInterfaceClearQoS(vm->def, olddev) < 0)
* virNetDevBandwidthSet:
* @ifname: on which interface
* @bandwidth: rates to set (may be NULL)
- * @hierarchical_class: whether to create hierarchical class
- * @swapped: true if IN/OUT should be set contrariwise
+ * @flags: bits indicating certain optional actions
*
+
* This function enables QoS on specified interface
* and set given traffic limits for both, incoming
- * and outgoing traffic. Any previous setting get
- * overwritten. If @hierarchical_class is TRUE, create
- * hierarchical class. It is used to guarantee minimal
- * throughput ('floor' attribute in NIC).
+ * and outgoing traffic.
+ *
+ * @flags bits and their meanings:
+ *
+ * VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS
+ * whether to create a hierarchical class
+ * A hiearchical class structure is used to implement a minimal
+ * throughput guarantee ('floor' attribute in NIC).
*
- * If @swapped is set, the IN part of @bandwidth is set on
- * @ifname's TX, and vice versa. If it is not set, IN is set on
- * RX and OUT on TX. This is because for some types of interfaces
- * domain and the host live on the same side of the interface (so
- * domain's RX/TX is host's RX/TX), and for some it's swapped
- * (domain's RX/TX is hosts's TX/RX).
+ * VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED
+ * set if IN/OUT should be set backwards from what's indicated in
+ * the bandwidth, i.e. the IN part of @bandwidth is set on
+ * @ifname's TX, and the OUT part of @bandwidth is set on
+ * @ifname's RX. This is needed because for some types of
+ * interfaces the domain and the host live on the same side of the
+ * interface (so domain's RX/TX is host's RX/TX), and for some
+ * it's swapped (domain's RX/TX is hosts's TX/RX).
*
* Return 0 on success, -1 otherwise.
*/
int
virNetDevBandwidthSet(const char *ifname,
const virNetDevBandwidth *bandwidth,
- bool hierarchical_class,
- bool swapped)
+ unsigned int flags)
{
int ret = -1;
virNetDevBandwidthRate *rx = NULL; /* From domain POV */
char *average = NULL;
char *peak = NULL;
char *burst = NULL;
+ bool hierarchical_class = flags & VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS;
if (!bandwidth) {
/* nothing to be enabled */
return -1;
}
- if (swapped) {
+ if (flags & VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED) {
rx = bandwidth->out;
tx = bandwidth->in;
} else {
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNetDevBandwidth, virNetDevBandwidthFree);
+typedef enum {
+ VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS = (1 << 0),
+ VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED = (1 << 1),
+} virNetDevBandwidthSetFlags;
+
int virNetDevBandwidthSet(const char *ifname,
const virNetDevBandwidth *bandwidth,
- bool hierarchical_class,
- bool swapped)
+ unsigned int flags)
G_GNUC_WARN_UNUSED_RESULT;
+
int virNetDevBandwidthClear(const char *ifname);
int virNetDevBandwidthCopy(virNetDevBandwidth **dest,
const virNetDevBandwidth *src)
if (virNetDevOpenvswitchInterfaceSetQos(iface, band, info->uuid, true) < 0)
return -1;
} else {
+ unsigned int flags = VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (info->hierarchical_class)
+ flags |= VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS;
+
exp_cmd = info->exp_cmd_tc;
- if (virNetDevBandwidthSet(iface, band, info->hierarchical_class, true) < 0)
+
+ if (virNetDevBandwidthSet(iface, band, flags) < 0)
return -1;
}