Devel
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- 28 participants
- 40117 discussions
[libvirt] [PATCH 5/5] blkiotune: add virsh support for blkiotune.throttle.iops/bps
by hzguanqiang@gmail.com 18 Sep '13
by hzguanqiang@gmail.com 18 Sep '13
18 Sep '13
From: Guan Qiang <hzguanqiang(a)corp.netease.com>
This adds four parameters --device-read-bps, --device-write-bps, --device-read-iops
and --device-write-iops to virsh command blkiotune for setting/getting
blkiotune.throttle.{read/write}_{iops/bps}_device.
---
tools/virsh-domain.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
tools/virsh.pod | 32 +++++++++++++++++++++++--
2 files changed, 94 insertions(+), 2 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 49cd154..2830d6a 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -1252,6 +1252,22 @@ static const vshCmdOptDef opts_blkiotune[] = {
.type = VSH_OT_STRING,
.help = N_("per-device IO Weights, in the form of /path/to/device,weight,...")
},
+ {.name = "device-read-bps",
+ .type = VSH_OT_STRING,
+ .help = N_("per-device read throughput limit in bytes per second, in the form of /path/to/device,read_bps,...")
+ },
+ {.name = "device-write-bps",
+ .type = VSH_OT_STRING,
+ .help = N_("per-device write throughput limit in bytes per second, in the form of /path/to/device,write_bps,...")
+ },
+ {.name = "device-read-iops",
+ .type = VSH_OT_STRING,
+ .help = N_("per-device read I/O operations limit per second, in the form of /path/to/device,read_iops,...")
+ },
+ {.name = "device-write-iops",
+ .type = VSH_OT_STRING,
+ .help = N_("per-device write I/O operations limit per second, in the form of /path/to/device,write_iops,...")
+ },
{.name = "config",
.type = VSH_OT_BOOL,
.help = N_("affect next boot")
@@ -1272,6 +1288,10 @@ cmdBlkiotune(vshControl * ctl, const vshCmd * cmd)
{
virDomainPtr dom;
const char *device_weight = NULL;
+ const char *device_read_bps = NULL;
+ const char *device_write_bps = NULL;
+ const char *device_read_iops = NULL;
+ const char *device_write_iops = NULL;
int weight = 0;
int nparams = 0;
int maxparams = 0;
@@ -1319,6 +1339,50 @@ cmdBlkiotune(vshControl * ctl, const vshCmd * cmd)
goto save_error;
}
+ rv = vshCommandOptString(cmd, "device-read-bps", &device_read_bps);
+ if (rv < 0) {
+ vshError(ctl, "%s", _("Unable to parse string parameter"));
+ goto cleanup;
+ } else if (rv > 0) {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ device_read_bps) < 0)
+ goto save_error;
+ }
+
+ rv = vshCommandOptString(cmd, "device-write-bps", &device_write_bps);
+ if (rv < 0) {
+ vshError(ctl, "%s", _("Unable to parse string parameter"));
+ goto cleanup;
+ } else if (rv > 0) {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ device_write_bps) < 0)
+ goto save_error;
+ }
+
+ rv = vshCommandOptString(cmd, "device-read-iops", &device_read_iops);
+ if (rv < 0) {
+ vshError(ctl, "%s", _("Unable to parse string parameter"));
+ goto cleanup;
+ } else if (rv > 0) {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ device_read_iops) < 0)
+ goto save_error;
+ }
+
+ rv = vshCommandOptString(cmd, "device-write-iops", &device_write_iops);
+ if (rv < 0) {
+ vshError(ctl, "%s", _("Unable to parse string parameter"));
+ goto cleanup;
+ } else if (rv > 0) {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ device_write_iops) < 0)
+ goto save_error;
+ }
+
if (nparams == 0) {
/* get the number of blkio parameters */
if (virDomainGetBlkioParameters(dom, NULL, &nparams, flags) != 0) {
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 0ae5178..69829eb 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1611,8 +1611,12 @@ The guaranteed minimum memory allocation for the guest.
Specifying -1 as a value for these limits is interpreted as unlimited.
=item B<blkiotune> I<domain> [I<--weight> B<weight>]
-[I<--device-weights> B<device-weights>] [[I<--config>]
-[I<--live>] | [I<--current>]]
+[I<--device-weights> B<device-weights>]
+[I<--device-read-bps> B<device-read-bps>]
+[I<--device-write-bps> B<device-write-bps>]
+[I<--device-read-iops> B<device-read-iops>]
+[I<--device-write-iops> B<device-write-iops>]
+[[I<--config>] [I<--live>] | [I<--current>]]
Display or set the blkio parameters. QEMU/KVM supports I<--weight>.
I<--weight> is in range [100, 1000].
@@ -1624,6 +1628,30 @@ device from per-device listings. Only the devices listed in the string
are modified; any existing per-device weights for other devices remain
unchanged.
+B<device-read-bps> is a single string listing one or more device/read_bps
+pairs, in the format of /path/to/device,read_bps,/path/to/device,read_bps.
+Each read_bps is a postive number, or the value 0 to remove that device from
+per-device listings. Only the devices listed in the string are modified;
+any existing per-device read_bps for other devices remain unchanged.
+
+B<device-write-bps> is a single string listing one or more device/write_bps
+pairs, in the format of /path/to/device,write_bps,/path/to/device,write_bps.
+Each write_bps is a postive number, or the value 0 to remove that device from
+per-device listings. Only the devices listed in the string are modified;
+any existing per-device write_bps for other devices remain unchanged.
+
+B<device-read-iops> is a single string listing one or more device/read_iops
+pairs, in the format of /path/to/device,read_iops,/path/to/device,read_iops.
+Each read_iops is a postive number, or the value 0 to remove that device from
+per-device listings. Only the devices listed in the string are modified;
+any existing per-device read_iops for other devices remain unchanged.
+
+B<device-write-iops> is a single string listing one or more device/write_iops
+pairs, in the format of /path/to/device,write_iops,/path/to/device,write_iops.
+Each write_iops is a postive number, or the value 0 to remove that device from
+per-device listings. Only the devices listed in the string are modified;
+any existing per-device write_iops for other devices remain unchanged.
+
If I<--live> is specified, affect a running guest.
If I<--config> is specified, affect the next boot of a persistent guest.
If I<--current> is specified, affect the current guest state.
--
1.7.9.5
1
0
[libvirt] [PATCH 4/5] blkiotune: add support for device iops and bps throttle
by hzguanqiang@gmail.com 18 Sep '13
by hzguanqiang@gmail.com 18 Sep '13
18 Sep '13
From: Guan Qiang <hzguanqiang(a)corp.netease.com>
This adds per-device iops and bps throttle to <blkiotune>. By
extending the existed 'domainSetBlkioParameters' interface,
read/write iops and bps throttle for per-device can be set
with blkio cgroup. The blkiotune xml entry is now looked like:
<domain ...>
<blkiotune>
<device>
<path>/path/to/block</path>
<weight>1000</weight>
<read_bps>100000</read_bps>
<write_bps>100000</write_bps>
<read_iops>100000</read_iops>
<write_iops>1000000</write_iops>
</device>
</blkiotune>
..
Elments <weight>,<read_bps>,<write_bps>,<read_iops>,<write_iops>
are all optional, but must have one.
---
docs/formatdomain.html.in | 8 +
docs/schemas/domaincommon.rng | 28 +-
include/libvirt/libvirt.h.in | 40 ++
src/conf/domain_conf.c | 115 +++-
src/conf/domain_conf.h | 16 +-
src/libvirt_private.syms | 4 +-
src/lxc/lxc_cgroup.c | 9 +-
src/qemu/qemu_cgroup.c | 10 +-
src/qemu/qemu_driver.c | 579 ++++++++++++++++++--
src/util/vircgroup.c | 79 ++-
src/util/vircgroup.h | 8 +-
.../qemuxml2argv-blkiotune-device.xml | 4 +
12 files changed, 789 insertions(+), 111 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index a927643..daf4f7a 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -753,10 +753,18 @@
<device>
<path>/dev/sda</path>
<weight>1000</weight>
+ <read_bps>20000000</read_bps>
+ <write_bps>30000000</write_bps>
+ <read_iops>4000</read_iops>
+ <write_iops>5000</write_iops>
</device>
<device>
<path>/dev/sdb</path>
<weight>500</weight>
+ <read_bps>30000000</read_bps>
+ <write_bps>30000000</write_bps>
+ <read_iops>4300</read_iops>
+ <write_iops>6000</write_iops>
</device>
</blkiotune>
...
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 4d333a8..10553af 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -621,9 +621,31 @@
<element name="path">
<ref name="absFilePath"/>
</element>
- <element name="weight">
- <ref name="weight"/>
- </element>
+ <optional>
+ <element name="weight">
+ <ref name="weight"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="read_bps">
+ <data type="unsignedLong"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="write_bps">
+ <data type="unsignedLong"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="read_iops">
+ <data type="unsignedLong"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="write_iops">
+ <data type="unsignedLong"/>
+ </element>
+ </optional>
</interleave>
</element>
</zeroOrMore>
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index a47e33c..fd4a2e5 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1780,6 +1780,46 @@ char * virDomainGetSchedulerType(virDomainPtr domain,
#define VIR_DOMAIN_BLKIO_DEVICE_WEIGHT "device_weight"
+/**
+ * VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS:
+ *
+ * Macro for the BLKIO tunable throttle.read_bps_device: it represents the read
+ * bytes per second permitted through a block device, as a string.
+ * The string is parsed as a series of /path/to/device,read_bps elements,
+ * separated by ',', with element read_bps as a ullong.
+ */
+#define VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS "device_read_bps"
+
+/**
+ * VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS:
+ *
+ * Macro for the BLKIO tunable throttle.write_bps_device: it represents the write
+ * bytes per second permitted through a block device, as a string.
+ * The string is parsed as a series of /path/to/device,write_bps elements,
+ * separated by ',', with element write_bps as a ullong.
+ */
+#define VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS "device_write_bps"
+
+/**
+ * VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS:
+ *
+ * Macro for the BLKIO tunable throttle.read_iops_device: it represents the read
+ * I/O operations per second permitted through a block device, as a string.
+ * The string is parsed as a series of /path/to/device,read_iops elements,
+ * separated by ',', with element read_iops as a ullong.
+ */
+#define VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS "device_read_iops"
+
+/**
+ * VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS:
+ *
+ * Macro for the BLKIO tunable throttle.write_iops_device: it represents the write
+ * I/O operations per second permitted through a block device, as a string.
+ * The string is parsed as a series of /path/to/device,write_iops elements,
+ * separated by ',', with element write_iops as a ullong.
+ */
+#define VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS "device_write_iops"
+
/* Set Blkio tunables for the domain*/
int virDomainSetBlkioParameters(virDomainPtr domain,
virTypedParameterPtr params,
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 05c1de4..f9df10f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -880,47 +880,100 @@ virDomainXMLOptionGetNamespace(virDomainXMLOptionPtr xmlopt)
void
-virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights,
+virBlkioDeviceIoTuneInfoArrayClear(virBlkioDeviceIoTuneInfoPtr devices,
int ndevices)
{
size_t i;
for (i = 0; i < ndevices; i++)
- VIR_FREE(deviceWeights[i].path);
+ VIR_FREE(devices[i].path);
}
/**
- * virDomainBlkioDeviceWeightParseXML
+ * virDomainBlkioDeviceIoTuneInfoParseXML
*
* this function parses a XML node:
*
* <device>
* <path>/fully/qualified/device/path</path>
* <weight>weight</weight>
+ * <read_bps>read_bps</read_bps>
+ * <write_bps>write_bps</write_bps>
+ * <read_iops>read_iops</read_iops>
+ * <write_iops>write_iops</write_iops>
* </device>
*
- * and fills a virBlkioDeviceWeight struct.
+ * and fills a virBlkioDeviceIoTuneInfo struct.
*/
static int
-virDomainBlkioDeviceWeightParseXML(xmlNodePtr root,
- virBlkioDeviceWeightPtr dw)
+virDomainBlkioDeviceIoTuneInfoParseXML(xmlNodePtr root,
+ virBlkioDeviceIoTuneInfoPtr dio)
{
char *c;
xmlNodePtr node;
+ dio->read_bps = 0;
+ dio->write_bps = 0;
+ dio->read_iops = 0;
+ dio->write_iops = 0;
+
node = root->children;
while (node) {
if (node->type == XML_ELEMENT_NODE) {
- if (xmlStrEqual(node->name, BAD_CAST "path") && !dw->path) {
- dw->path = (char *)xmlNodeGetContent(node);
+ if (xmlStrEqual(node->name, BAD_CAST "path") && !dio->path) {
+ dio->path = (char *)xmlNodeGetContent(node);
} else if (xmlStrEqual(node->name, BAD_CAST "weight")) {
c = (char *)xmlNodeGetContent(node);
- if (virStrToLong_ui(c, NULL, 10, &dw->weight) < 0) {
+ if (virStrToLong_ui(c, NULL, 10, &dio->weight) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("could not parse weight %s"),
c);
VIR_FREE(c);
- VIR_FREE(dw->path);
+ VIR_FREE(dio->path);
+ return -1;
+ }
+ VIR_FREE(c);
+ } else if (xmlStrEqual(node->name, BAD_CAST "read_bps")) {
+ c = (char *)xmlNodeGetContent(node);
+ if (virStrToLong_ull(c, NULL, 10, &dio->read_bps) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not parse read_bps %s"),
+ c);
+ VIR_FREE(c);
+ VIR_FREE(dio->path);
+ return -1;
+ }
+ VIR_FREE(c);
+ } else if (xmlStrEqual(node->name, BAD_CAST "write_bps")) {
+ c = (char *)xmlNodeGetContent(node);
+ if (virStrToLong_ull(c, NULL, 10, &dio->write_bps) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not parse write_bps %s"),
+ c);
+ VIR_FREE(c);
+ VIR_FREE(dio->path);
+ return -1;
+ }
+ VIR_FREE(c);
+ } else if (xmlStrEqual(node->name, BAD_CAST "read_iops")) {
+ c = (char *)xmlNodeGetContent(node);
+ if (virStrToLong_ull(c, NULL, 10, &dio->read_iops) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not parse read_iops %s"),
+ c);
+ VIR_FREE(c);
+ VIR_FREE(dio->path);
+ return -1;
+ }
+ VIR_FREE(c);
+ } else if (xmlStrEqual(node->name, BAD_CAST "write_iops")) {
+ c = (char *)xmlNodeGetContent(node);
+ if (virStrToLong_ull(c, NULL, 10, &dio->write_iops) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not parse write_iops %s"),
+ c);
+ VIR_FREE(c);
+ VIR_FREE(dio->path);
return -1;
}
VIR_FREE(c);
@@ -928,7 +981,7 @@ virDomainBlkioDeviceWeightParseXML(xmlNodePtr root,
}
node = node->next;
}
- if (!dw->path) {
+ if (!dio->path) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("missing per-device path"));
return -1;
@@ -1988,8 +2041,8 @@ void virDomainDefFree(virDomainDefPtr def)
VIR_FREE(def->description);
VIR_FREE(def->title);
- virBlkioDeviceWeightArrayClear(def->blkio.devices,
- def->blkio.ndevices);
+ virBlkioDeviceIoTuneInfoArrayClear(def->blkio.devices,
+ def->blkio.ndevices);
VIR_FREE(def->blkio.devices);
virDomainWatchdogDefFree(def->watchdog);
@@ -10962,15 +11015,15 @@ virDomainDefParseXML(xmlDocPtr xml,
for (i = 0; i < n; i++) {
size_t j;
- if (virDomainBlkioDeviceWeightParseXML(nodes[i],
- &def->blkio.devices[i]) < 0)
+ if (virDomainBlkioDeviceIoTuneInfoParseXML(nodes[i],
+ &def->blkio.devices[i]) < 0)
goto error;
def->blkio.ndevices++;
for (j = 0; j < i; j++) {
if (STREQ(def->blkio.devices[j].path,
def->blkio.devices[i].path)) {
virReportError(VIR_ERR_XML_ERROR,
- _("duplicate device weight path '%s'"),
+ _("duplicate blkio device path '%s'"),
def->blkio.devices[i].path);
goto error;
}
@@ -16349,7 +16402,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
blkio = true;
} else {
for (n = 0; n < def->blkio.ndevices; n++) {
- if (def->blkio.devices[n].weight) {
+ if (def->blkio.devices[n].weight || def->blkio.devices[n].read_bps ||
+ def->blkio.devices[n].write_bps || def->blkio.devices[n].read_iops ||
+ def->blkio.devices[n].write_iops) {
blkio = true;
break;
}
@@ -16364,13 +16419,33 @@ virDomainDefFormatInternal(virDomainDefPtr def,
def->blkio.weight);
for (n = 0; n < def->blkio.ndevices; n++) {
- if (def->blkio.devices[n].weight == 0)
+ if (def->blkio.devices[n].weight == 0 && def->blkio.devices[n].read_bps == 0 &&
+ def->blkio.devices[n].write_bps == 0 && def->blkio.devices[n].read_iops == 0 &&
+ def->blkio.devices[n].write_iops == 0)
continue;
virBufferAddLit(buf, " <device>\n");
virBufferEscapeString(buf, " <path>%s</path>\n",
def->blkio.devices[n].path);
- virBufferAsprintf(buf, " <weight>%u</weight>\n",
- def->blkio.devices[n].weight);
+ if (def->blkio.devices[n].weight) {
+ virBufferAsprintf(buf, " <weight>%u</weight>\n",
+ def->blkio.devices[n].weight);
+ }
+ if (def->blkio.devices[n].read_bps) {
+ virBufferAsprintf(buf, " <read_bps>%llu</read_bps>\n",
+ def->blkio.devices[n].read_bps);
+ }
+ if (def->blkio.devices[n].write_bps) {
+ virBufferAsprintf(buf, " <write_bps>%llu</write_bps>\n",
+ def->blkio.devices[n].write_bps);
+ }
+ if (def->blkio.devices[n].read_iops) {
+ virBufferAsprintf(buf, " <read_iops>%llu</read_iops>\n",
+ def->blkio.devices[n].read_iops);
+ }
+ if (def->blkio.devices[n].write_iops) {
+ virBufferAsprintf(buf, " <write_iops>%llu</write_iops>\n",
+ def->blkio.devices[n].write_iops);
+ }
virBufferAddLit(buf, " </device>\n");
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9414ebf..1f350ed 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1857,11 +1857,15 @@ virDomainVcpuPinDefPtr virDomainVcpuPinFindByVcpu(virDomainVcpuPinDefPtr *def,
int nvcpupin,
int vcpu);
-typedef struct _virBlkioDeviceWeight virBlkioDeviceWeight;
-typedef virBlkioDeviceWeight *virBlkioDeviceWeightPtr;
-struct _virBlkioDeviceWeight {
+typedef struct _virBlkioDeviceIoTuneInfo virBlkioDeviceIoTuneInfo;
+typedef virBlkioDeviceIoTuneInfo *virBlkioDeviceIoTuneInfoPtr;
+struct _virBlkioDeviceIoTuneInfo {
char *path;
unsigned int weight;
+ unsigned long long read_bps;
+ unsigned long long write_bps;
+ unsigned long long read_iops;
+ unsigned long long write_iops;
};
enum virDomainRNGModel {
@@ -1908,8 +1912,8 @@ struct _virDomainIdMapDef {
};
-void virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights,
- int ndevices);
+void virBlkioDeviceIoTuneInfoArrayClear(virBlkioDeviceIoTuneInfoPtr devices,
+ int ndevices);
typedef struct _virDomainResourceDef virDomainResourceDef;
typedef virDomainResourceDef *virDomainResourceDefPtr;
@@ -1937,7 +1941,7 @@ struct _virDomainDef {
unsigned int weight;
size_t ndevices;
- virBlkioDeviceWeightPtr devices;
+ virBlkioDeviceIoTuneInfoPtr devices;
} blkio;
struct {
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 50e2f48..e6259cf 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -103,7 +103,7 @@ virDomainAuditVcpu;
# conf/domain_conf.h
-virBlkioDeviceWeightArrayClear;
+virBlkioDeviceIoTuneInfoArrayClear;
virDiskNameToBusDeviceIndex;
virDiskNameToIndex;
virDomainActualNetDefFree;
@@ -1207,7 +1207,7 @@ virCgroupNewVcpu;
virCgroupPathOfController;
virCgroupRemove;
virCgroupRemoveRecursively;
-virCgroupSetBlkioDeviceWeight;
+virCgroupSetBlkioDeviceIoTune;
virCgroupSetBlkioWeight;
virCgroupSetCpuCfsPeriod;
virCgroupSetCpuCfsQuota;
diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index 0b0ca02..f2c32e7 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -112,10 +112,13 @@ static int virLXCCgroupSetupBlkioTune(virDomainDefPtr def,
if (def->blkio.ndevices) {
for (i = 0; i < def->blkio.ndevices; i++) {
- virBlkioDeviceWeightPtr dw = &def->blkio.devices[i];
- if (!dw->weight)
+ virBlkioDeviceIoTuneInfoPtr dio = &def->blkio.devices[i];
+ if (!dio->weight)
continue;
- if (virCgroupSetBlkioDeviceWeight(cgroup, dw->path, dw->weight) < 0)
+ if (virCgroupSetBlkioDeviceIoTune(cgroup,
+ dio->path, dio->weight,
+ dio->read_bps, dio->write_bps,
+ dio->read_iops, dio->write_iops) < 0)
return -1;
}
}
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index f95c7f2..20e700f 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -399,11 +399,13 @@ qemuSetupBlkioCgroup(virDomainObjPtr vm)
if (vm->def->blkio.ndevices) {
for (i = 0; i < vm->def->blkio.ndevices; i++) {
- virBlkioDeviceWeightPtr dw = &vm->def->blkio.devices[i];
- if (!dw->weight)
+ virBlkioDeviceIoTuneInfoPtr dio = &vm->def->blkio.devices[i];
+ if (!dio->weight)
continue;
- if (virCgroupSetBlkioDeviceWeight(priv->cgroup, dw->path,
- dw->weight) < 0)
+ if (virCgroupSetBlkioDeviceIoTune(priv->cgroup,
+ dio->path, dio->weight,
+ dio->read_bps, dio->write_bps,
+ dio->read_iops, dio->write_iops) < 0)
return -1;
}
}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0763f9b..ff0ae98 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -131,7 +131,7 @@
# define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */
#endif
-#define QEMU_NB_BLKIO_PARAM 2
+#define QEMU_NB_BLKIO_PARAM 6
#define QEMU_NB_BANDWIDTH_PARAM 6
@@ -7388,26 +7388,26 @@ cleanup:
return ret;
}
-/* deviceWeightStr in the form of /device/path,weight,/device/path,weight
+/* deviceIoTuneStr in the form of /device/path,ioTuneValue,/device/path,ioTuneValue or
* for example, /dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0,800
+ * deviceIoTuneFiled represents the ioTune type to tune, including device weight,
+ * device read bps, device write bps, device read iops and device write iops.
*/
static int
-qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
- virBlkioDeviceWeightPtr *dw, size_t *size)
+qemuDomainParseDeviceIoTuneInfoStr(char *deviceIoTuneStr,
+ const char *deviceIoTuneFiled,
+ virBlkioDeviceIoTuneInfoPtr *dio, size_t *size)
{
char *temp;
int ndevices = 0;
int nsep = 0;
- size_t i;
- virBlkioDeviceWeightPtr result = NULL;
-
- *dw = NULL;
- *size = 0;
+ size_t i, j, k;
+ virBlkioDeviceIoTuneInfoPtr result = NULL;
- if (STREQ(deviceWeightStr, ""))
+ if (STREQ(deviceIoTuneStr, ""))
return 0;
- temp = deviceWeightStr;
+ temp = deviceIoTuneStr;
while (temp) {
temp = strchr(temp, ',');
if (temp) {
@@ -7426,8 +7426,11 @@ qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
if (VIR_ALLOC_N(result, ndevices) < 0)
return -1;
+ for (i = 0; i < ndevices; i++)
+ memset(&result[i], 0, sizeof(result[i]));
+
i = 0;
- temp = deviceWeightStr;
+ temp = deviceIoTuneStr;
while (temp) {
char *p = temp;
@@ -7439,11 +7442,25 @@ qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
if (VIR_STRNDUP(result[i].path, temp, p - temp) < 0)
goto cleanup;
- /* weight */
+ /* device ioTune value */
temp = p + 1;
- if (virStrToLong_ui(temp, &p, 10, &result[i].weight) < 0)
- goto error;
+ if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
+ if (virStrToLong_ui(temp, &p, 10, &result[i].weight) < 0)
+ goto error;
+ } else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS)) {
+ if (virStrToLong_ull(temp, &p, 10, &result[i].read_bps) < 0)
+ goto error;
+ } else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS)) {
+ if (virStrToLong_ull(temp, &p, 10, &result[i].write_bps) < 0)
+ goto error;
+ } else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS)) {
+ if (virStrToLong_ull(temp, &p, 10, &result[i].read_iops) < 0)
+ goto error;
+ } else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS)) {
+ if (virStrToLong_ull(temp, &p, 10, &result[i].write_iops) < 0)
+ goto error;
+ }
i++;
@@ -7457,30 +7474,68 @@ qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
if (!i)
VIR_FREE(result);
- *dw = result;
- *size = i;
+ for (j = 0; j < i; j++) {
+ bool found = false;
+ virBlkioDeviceIoTuneInfoPtr old, new;
+
+ new = &result[j];
+ for (k = 0; k < *size; k++) {
+ old = &(*dio)[k];
+ if (STREQ(new->path, old->path)) {
+ found = true;
+ if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT))
+ old->weight = new->weight;
+ else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS))
+ old->read_bps = new->read_bps;
+ else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS))
+ old->write_bps = new->write_bps;
+ else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS))
+ old->read_iops = new->read_iops;
+ else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS))
+ old->write_iops = new->write_iops;
+ break;
+ }
+ }
+ if (!found) {
+ if (!new->weight && !new->read_bps && !new->write_bps &&
+ !new->read_iops && !new->write_iops)
+ continue;
+ if (VIR_EXPAND_N(*dio, *size, 1) < 0)
+ goto cleanup;
+ old = &(*dio)[*size -1];
+ if (VIR_STRDUP(old->path, new->path) < 0)
+ goto cleanup;
+ old->weight = new->weight;
+ old->read_bps = new->read_bps;
+ old->write_bps = new->write_bps;
+ old->read_iops = new->read_iops;
+ old->write_iops = new->write_iops;
+ }
+ }
+ virBlkioDeviceIoTuneInfoArrayClear(result, ndevices);
+ VIR_FREE(result);
return 0;
error:
virReportError(VIR_ERR_INVALID_ARG,
- _("unable to parse device weight '%s'"), deviceWeightStr);
+ _("unable to parse device ioTune '%s'"), deviceIoTuneStr);
cleanup:
- virBlkioDeviceWeightArrayClear(result, ndevices);
+ virBlkioDeviceIoTuneInfoArrayClear(result, ndevices);
VIR_FREE(result);
return -1;
}
-/* Modify dest_array to reflect all device weight changes described in
+/* Modify dest_array to reflect all device Iotune info changes described in
* src_array. */
static int
-qemuDomainMergeDeviceWeights(virBlkioDeviceWeightPtr *dest_array,
- size_t *dest_size,
- virBlkioDeviceWeightPtr src_array,
- size_t src_size)
+qemuDomainMergeDeviceIoTuneInfos(virBlkioDeviceIoTuneInfoPtr *dest_array,
+ size_t *dest_size,
+ virBlkioDeviceIoTuneInfoPtr src_array,
+ size_t src_size)
{
size_t i, j;
- virBlkioDeviceWeightPtr dest, src;
+ virBlkioDeviceIoTuneInfoPtr dest, src;
for (i = 0; i < src_size; i++) {
bool found = false;
@@ -7491,18 +7546,27 @@ qemuDomainMergeDeviceWeights(virBlkioDeviceWeightPtr *dest_array,
if (STREQ(src->path, dest->path)) {
found = true;
dest->weight = src->weight;
+ dest->read_bps = src->read_bps;
+ dest->write_bps = src->write_bps;
+ dest->read_iops = src->read_iops;
+ dest->write_iops = src->write_iops;
break;
}
}
if (!found) {
- if (!src->weight)
+ if (!src->weight && !src->read_bps && !src->write_bps &&
+ !src->read_iops && !src->write_iops)
continue;
if (VIR_EXPAND_N(*dest_array, *dest_size, 1) < 0)
return -1;
dest = &(*dest_array)[*dest_size - 1];
- dest->path = src->path;
+ if (VIR_STRDUP(dest->path, src->path) < 0)
+ return -1;
dest->weight = src->weight;
- src->path = NULL;
+ dest->read_bps = src->read_bps;
+ dest->write_bps = src->write_bps;
+ dest->read_iops = src->read_iops;
+ dest->write_iops = src->write_iops;
}
}
@@ -7531,6 +7595,14 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
VIR_TYPED_PARAM_UINT,
VIR_DOMAIN_BLKIO_DEVICE_WEIGHT,
VIR_TYPED_PARAM_STRING,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ VIR_TYPED_PARAM_STRING,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ VIR_TYPED_PARAM_STRING,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ VIR_TYPED_PARAM_STRING,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ VIR_TYPED_PARAM_STRING,
NULL) < 0)
return -1;
@@ -7562,44 +7634,114 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
for (i = 0; i < nparams; i++) {
virTypedParameterPtr param = ¶ms[i];
+ size_t ndevices = 0;
+ virBlkioDeviceIoTuneInfoPtr devices = NULL;
+ size_t j;
+
+ if (qemuDomainMergeDeviceIoTuneInfos(&devices, &ndevices,
+ vm->def->blkio.devices,
+ vm->def->blkio.ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
if (params[i].value.ui > 1000 || params[i].value.ui < 100) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("out of blkio weight range."));
ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
continue;
}
if (virCgroupSetBlkioWeight(priv->cgroup, params[i].value.ui) < 0)
ret = -1;
} else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
- size_t ndevices;
- virBlkioDeviceWeightPtr devices = NULL;
- size_t j;
-
- if (qemuDomainParseDeviceWeightStr(params[i].value.s,
- &devices,
- &ndevices) < 0) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_DEVICE_WEIGHT,
+ &devices,
+ &ndevices) < 0) {
ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
continue;
}
- for (j = 0; j < ndevices; j++) {
- if (virCgroupSetBlkioDeviceWeight(priv->cgroup,
- devices[j].path,
- devices[j].weight) < 0) {
- ret = -1;
- break;
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
}
+ continue;
}
- if (j != ndevices ||
- qemuDomainMergeDeviceWeights(&vm->def->blkio.devices,
- &vm->def->blkio.ndevices,
- devices, ndevices) < 0)
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ }
+
+ for (j = 0; j < ndevices; j++) {
+ if (virCgroupSetBlkioDeviceIoTune(priv->cgroup,
+ devices[j].path, devices[j].weight,
+ devices[j].read_bps, devices[j].write_bps,
+ devices[j].read_iops, devices[j].write_iops) < 0) {
ret = -1;
- virBlkioDeviceWeightArrayClear(devices, ndevices);
- VIR_FREE(devices);
+ break;
+ }
}
+ if (j != ndevices ||
+ qemuDomainMergeDeviceIoTuneInfos(&vm->def->blkio.devices,
+ &vm->def->blkio.ndevices,
+ devices, ndevices) < 0)
+ ret = -1;
+
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
}
}
if (ret < 0)
@@ -7610,33 +7752,102 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
for (i = 0; i < nparams; i++) {
virTypedParameterPtr param = ¶ms[i];
+ virBlkioDeviceIoTuneInfoPtr devices = NULL;
+ size_t ndevices = 0;
+
+ if (qemuDomainMergeDeviceIoTuneInfos(&devices, &ndevices,
+ persistentDef->blkio.devices,
+ persistentDef->blkio.ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
if (params[i].value.ui > 1000 || params[i].value.ui < 100) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("out of blkio weight range."));
ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
continue;
}
persistentDef->blkio.weight = params[i].value.ui;
} else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
- virBlkioDeviceWeightPtr devices = NULL;
- size_t ndevices;
-
- if (qemuDomainParseDeviceWeightStr(params[i].value.s,
- &devices,
- &ndevices) < 0) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_DEVICE_WEIGHT,
+ &devices,
+ &ndevices) < 0) {
ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
continue;
}
- if (qemuDomainMergeDeviceWeights(&persistentDef->blkio.devices,
- &persistentDef->blkio.ndevices,
- devices, ndevices) < 0)
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ &devices,
+ &ndevices) < 0) {
ret = -1;
- virBlkioDeviceWeightArrayClear(devices, ndevices);
- VIR_FREE(devices);
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
}
+
+ if (qemuDomainMergeDeviceIoTuneInfos(&persistentDef->blkio.devices,
+ &persistentDef->blkio.ndevices,
+ devices, ndevices) < 0)
+ ret = -1;
+
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
}
if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
@@ -7747,6 +7958,122 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
goto cleanup;
break;
+ case 2: /* blkiotune.throttle.device_read_bps */
+ if (vm->def->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < vm->def->blkio.ndevices; j++) {
+ if (!vm->def->blkio.devices[j].read_bps)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ vm->def->blkio.devices[j].path,
+ vm->def->blkio.devices[j].read_bps);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (virTypedParameterAssign(param,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ VIR_TYPED_PARAM_STRING,
+ param->value.s) < 0)
+ goto cleanup;
+ break;
+
+ case 3: /* blkiotune.throttle.device_write_bps */
+ if (vm->def->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < vm->def->blkio.ndevices; j++) {
+ if (!vm->def->blkio.devices[j].write_bps)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ vm->def->blkio.devices[j].path,
+ vm->def->blkio.devices[j].write_bps);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (virTypedParameterAssign(param,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ VIR_TYPED_PARAM_STRING,
+ param->value.s) < 0)
+ goto cleanup;
+ break;
+
+ case 4: /* blkiotune.throttle.device_read_iops */
+ if (vm->def->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < vm->def->blkio.ndevices; j++) {
+ if (!vm->def->blkio.devices[j].read_iops)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ vm->def->blkio.devices[j].path,
+ vm->def->blkio.devices[j].read_iops);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (virTypedParameterAssign(param,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ VIR_TYPED_PARAM_STRING,
+ param->value.s) < 0)
+ goto cleanup;
+ break;
+
+ case 5: /* blkiotune.throttle.device_write_iops */
+ if (vm->def->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < vm->def->blkio.ndevices; j++) {
+ if (!vm->def->blkio.devices[j].write_iops)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ vm->def->blkio.devices[j].path,
+ vm->def->blkio.devices[j].write_iops);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (virTypedParameterAssign(param,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ VIR_TYPED_PARAM_STRING,
+ param->value.s) < 0)
+ goto cleanup;
+ break;
+
default:
break;
/* should not hit here */
@@ -7804,6 +8131,142 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
}
break;
+ case 2: /* blkiotune.device_read_bps */
+ if (persistentDef->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < persistentDef->blkio.ndevices; j++) {
+ if (!persistentDef->blkio.devices[j].read_bps)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ persistentDef->blkio.devices[j].path,
+ persistentDef->blkio.devices[j].read_bps);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (!param->value.s && VIR_STRDUP(param->value.s, "") < 0)
+ goto cleanup;
+ param->type = VIR_TYPED_PARAM_STRING;
+ if (virStrcpyStatic(param->field,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field name '%s' too long"),
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS);
+ goto cleanup;
+ }
+ break;
+
+ case 3: /* blkiotune.device_write_bps */
+ if (persistentDef->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < persistentDef->blkio.ndevices; j++) {
+ if (!persistentDef->blkio.devices[j].write_bps)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ persistentDef->blkio.devices[j].path,
+ persistentDef->blkio.devices[j].write_bps);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (!param->value.s && VIR_STRDUP(param->value.s, "") < 0)
+ goto cleanup;
+ param->type = VIR_TYPED_PARAM_STRING;
+ if (virStrcpyStatic(param->field,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field name '%s' too long"),
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS);
+ goto cleanup;
+ }
+ break;
+
+ case 4: /* blkiotune.device_read_iops */
+ if (persistentDef->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < persistentDef->blkio.ndevices; j++) {
+ if (!persistentDef->blkio.devices[j].read_iops)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ persistentDef->blkio.devices[j].path,
+ persistentDef->blkio.devices[j].read_iops);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (!param->value.s && VIR_STRDUP(param->value.s, "") < 0)
+ goto cleanup;
+ param->type = VIR_TYPED_PARAM_STRING;
+ if (virStrcpyStatic(param->field,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field name '%s' too long"),
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS);
+ goto cleanup;
+ }
+ break;
+
+ case 5: /* blkiotune.device_write_iops */
+ if (persistentDef->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < persistentDef->blkio.ndevices; j++) {
+ if (!persistentDef->blkio.devices[j].write_iops)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ persistentDef->blkio.devices[j].path,
+ persistentDef->blkio.devices[j].write_iops);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (!param->value.s && VIR_STRDUP(param->value.s, "") < 0)
+ goto cleanup;
+ param->type = VIR_TYPED_PARAM_STRING;
+ if (virStrcpyStatic(param->field,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field name '%s' too long"),
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS);
+ goto cleanup;
+ }
+ break;
+
default:
break;
/* should not hit here */
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index e99caf5..b506de5 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -1825,23 +1825,36 @@ virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight)
/**
- * virCgroupSetBlkioDeviceWeight:
+ * virCgroupSetBlkioDeviceIoTune:
*
- * @group: The cgroup to change io device weight device for
+ * @group: The cgroup to change io device iotune device for
* @path: The device with a weight to alter
* @weight: The new device weight (100-1000), or 0 to clear
+ * @read_bps: The new read bps throttle, or 0 to clear
+ * @write_bps: The new write bps throttle, or 0 to clear
+ * @read_iops: The new read iops throttle, or 0 to clear
+ * @write_iops: The new write iops throttle, or 0 to clear
*
- * device_weight is treated as a write-only parameter, so
- * there isn't a getter counterpart.
+ * paramters like device_weight, device_read_bps, device_write_bps,
+ * device_read_iops and device_write_iops are treated as write-only,
+ * so there isn't a getter counterpart.
*
* Returns: 0 on success, -1 on error
*/
int
-virCgroupSetBlkioDeviceWeight(virCgroupPtr group,
+virCgroupSetBlkioDeviceIoTune(virCgroupPtr group,
const char *path,
- unsigned int weight)
-{
- char *str;
+ unsigned int weight,
+ unsigned long long read_bps,
+ unsigned long long write_bps,
+ unsigned long long read_iops,
+ unsigned long long write_iops)
+{
+ char *weight_str;
+ char *read_bps_str;
+ char *write_bps_str;
+ char *read_iops_str;
+ char *write_iops_str;
struct stat sb;
int ret;
@@ -1866,15 +1879,51 @@ virCgroupSetBlkioDeviceWeight(virCgroupPtr group,
return -1;
}
- if (virAsprintf(&str, "%d:%d %d", major(sb.st_rdev), minor(sb.st_rdev),
+ if (virAsprintf(&weight_str, "%d:%d %d", major(sb.st_rdev), minor(sb.st_rdev),
weight) < 0)
return -1;
+ if (virAsprintf(&read_bps_str, "%d:%d %llu", major(sb.st_rdev), minor(sb.st_rdev),
+ read_bps) < 0)
+ return -1;
+
+ if (virAsprintf(&write_bps_str, "%d:%d %llu", major(sb.st_rdev), minor(sb.st_rdev),
+ write_bps) < 0)
+ return -1;
+
+ if (virAsprintf(&read_iops_str, "%d:%d %llu", major(sb.st_rdev), minor(sb.st_rdev),
+ read_iops) < 0)
+ return -1;
+
+ if (virAsprintf(&write_iops_str, "%d:%d %llu", major(sb.st_rdev), minor(sb.st_rdev),
+ write_iops) < 0)
+ return -1;
+
ret = virCgroupSetValueStr(group,
VIR_CGROUP_CONTROLLER_BLKIO,
"blkio.weight_device",
- str);
- VIR_FREE(str);
+ weight_str);
+ ret = virCgroupSetValueStr(group,
+ VIR_CGROUP_CONTROLLER_BLKIO,
+ "blkio.throttle.read_bps_device",
+ read_bps_str);
+ ret = virCgroupSetValueStr(group,
+ VIR_CGROUP_CONTROLLER_BLKIO,
+ "blkio.throttle.write_bps_device",
+ write_bps_str);
+ ret = virCgroupSetValueStr(group,
+ VIR_CGROUP_CONTROLLER_BLKIO,
+ "blkio.throttle.read_iops_device",
+ read_iops_str);
+ ret = virCgroupSetValueStr(group,
+ VIR_CGROUP_CONTROLLER_BLKIO,
+ "blkio.throttle.write_iops_device",
+ write_iops_str);
+ VIR_FREE(weight_str);
+ VIR_FREE(read_bps_str);
+ VIR_FREE(write_bps_str);
+ VIR_FREE(read_iops_str);
+ VIR_FREE(write_iops_str);
return ret;
}
@@ -3287,9 +3336,13 @@ virCgroupGetBlkioWeight(virCgroupPtr group ATTRIBUTE_UNUSED,
int
-virCgroupSetBlkioDeviceWeight(virCgroupPtr group ATTRIBUTE_UNUSED,
+virCgroupSetBlkioDeviceIoTune(virCgroupPtr group ATTRIBUTE_UNUSED,
const char *path ATTRIBUTE_UNUSED,
- unsigned int weight ATTRIBUTE_UNUSED)
+ unsigned int weight ATTRIBUTE_UNUSED,
+ unsigned long long read_bps ATTRIBUTE_UNUSED,
+ unsigned long long write_bps ATTRIBUTE_UNUSED,
+ unsigned long long read_iops ATTRIBUTE_UNUSED,
+ unsigned long long write_iops ATTRIBUTE_UNUSED)
{
virReportSystemError(ENOSYS, "%s",
_("Control groups not supported on this platform"));
diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
index 835eb30..21980da 100644
--- a/src/util/vircgroup.h
+++ b/src/util/vircgroup.h
@@ -122,9 +122,13 @@ int virCgroupMoveTask(virCgroupPtr src_group,
int virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight);
int virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight);
-int virCgroupSetBlkioDeviceWeight(virCgroupPtr group,
+int virCgroupSetBlkioDeviceIoTune(virCgroupPtr group,
const char *path,
- unsigned int weight);
+ unsigned int weight,
+ unsigned long long read_bps,
+ unsigned long long write_bps,
+ unsigned long long read_iops,
+ unsigned long long write_iops);
int virCgroupSetMemory(virCgroupPtr group, unsigned long long kb);
int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml
index 743cf29..9bd97fe 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml
@@ -8,6 +8,10 @@
<device>
<path>/dev/sda</path>
<weight>400</weight>
+ <read_bps>2000000000</read_bps>
+ <write_bps>1000000000</write_bps>
+ <read_iops>1000</read_iops>
+ <write_iops>2000</write_iops>
</device>
<device>
<path>/dev/sdb</path>
--
1.7.9.5
1
0
18 Sep '13
From: Aline Manera <alinefm(a)br.ibm.com>
qemu/KVM also supports a tftp URL while specifying the cdrom ISO image.
The xml should be as following:
<disk type='network' device='cdrom'>
<source protocol='tftp' name='/url/path'>
<host name='host.name' port='69'/>
</source>
</disk>
Signed-off-by: Aline Manera <alinefm(a)br.ibm.com>
---
docs/formatdomain.html.in | 8 +++++
docs/schemas/domaincommon.rng | 1 +
src/conf/domain_conf.c | 3 +-
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 6 ++++
.../qemuxml2argv-disk-cdrom-network-tftp.args | 7 ++++
.../qemuxml2argv-disk-cdrom-network-tftp.xml | 37 ++++++++++++++++++++
tests/qemuxml2argvtest.c | 2 ++
8 files changed, 64 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 0b6cd45..a927643 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1533,6 +1533,14 @@
<target dev='hdc' bus='ide' tray='open'/>
<readonly/>
</disk>
+ <disk type='network' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source protocol="tftp" name="url_path">
+ <host name="hostname" port="69"/>
+ </source>
+ <target dev='hdc' bus='ide' tray='open'/>
+ <readonly/>
+ </disk>
<disk type='block' device='lun'>
<driver name='qemu' type='raw'/>
<source dev='/dev/sda'/>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 2da3669..4d333a8 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1234,6 +1234,7 @@
<value>https</value>
<value>ftp</value>
<value>ftps</value>
+ <value>tftp</value>
</choice>
</attribute>
<optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ff3da7a..05c1de4 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -267,7 +267,8 @@ VIR_ENUM_IMPL(virDomainDiskProtocol, VIR_DOMAIN_DISK_PROTOCOL_LAST,
"http",
"https",
"ftp",
- "ftps")
+ "ftps",
+ "tftp")
VIR_ENUM_IMPL(virDomainDiskProtocolTransport, VIR_DOMAIN_DISK_PROTO_TRANS_LAST,
"tcp",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ab1290b..9414ebf 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -546,6 +546,7 @@ enum virDomainDiskProtocol {
VIR_DOMAIN_DISK_PROTOCOL_HTTPS,
VIR_DOMAIN_DISK_PROTOCOL_FTP,
VIR_DOMAIN_DISK_PROTOCOL_FTPS,
+ VIR_DOMAIN_DISK_PROTOCOL_TFTP,
VIR_DOMAIN_DISK_PROTOCOL_LAST
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1bde013..4628dac 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3923,6 +3923,12 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
disk->hosts->port ? disk->hosts->port : "990");
virBufferEscape(&opt, ',', ",", "%s,", disk->src);
break;
+ case VIR_DOMAIN_DISK_PROTOCOL_TFTP:
+ virBufferAsprintf(&opt, "file=tftp://%s:%s",
+ disk->hosts->name,
+ disk->hosts->port ? disk->hosts->port : "69");
+ virBufferEscape(&opt, ',', ",", "%s,", disk->src);
+ break;
}
} else if (disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME) {
if (qemuBuildVolumeString(conn, disk, &opt) < 0)
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.args
new file mode 100644
index 0000000..bc0cb92
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.args
@@ -0,0 +1,7 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/kvm -S \
+-M pc-1.2 -m 1024 -smp 1 -nographic -nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait -boot d -usb \
+-drive file=tftp://host.name:69/url/path/file.iso,if=none,media=cdrom,id=drive-ide0-1-0 \
+-device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.xml
new file mode 100644
index 0000000..b311237
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.xml
@@ -0,0 +1,37 @@
+<domain type='kvm'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-1.2'>hvm</type>
+ <boot dev='cdrom'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/bin/kvm</emulator>
+ <disk type='network' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source protocol='tftp' name='/url/path/file.iso'>
+ <host name='host.name' port='69'/>
+ </source>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ <alias name='ide0-1-0'/>
+ <address type='drive' controller='0' bus='1' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 5daee82..ec4a6e5 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -451,6 +451,8 @@ mymain(void)
QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-network-ftps", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE,
QEMU_CAPS_DRIVE);
+ DO_TEST("disk-cdrom-network-tftp", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE,
+ QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-empty", QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-tray",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_VIRTIO_TX_ALG);
--
1.7.9.5
1
0
18 Sep '13
From: Aline Manera <alinefm(a)br.ibm.com>
The ftps protocol is another protocol supported by qemu/KVM while specifying
the cdrom ISO image.
The xml should be as following:
<disk type='network' device='cdrom'>
<source protocol='ftps' name='/url/path'>
<host name='host.name' port='990'/>
</source>
</disk>
Signed-off-by: Aline Manera <alinefm(a)br.ibm.com>
---
docs/formatdomain.html.in | 8 +++++
docs/schemas/domaincommon.rng | 1 +
src/conf/domain_conf.c | 3 +-
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 6 ++++
.../qemuxml2argv-disk-cdrom-network-ftps.args | 8 +++++
.../qemuxml2argv-disk-cdrom-network-ftps.xml | 37 ++++++++++++++++++++
tests/qemuxml2argvtest.c | 2 ++
8 files changed, 65 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 240571f..0b6cd45 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1525,6 +1525,14 @@
<target dev='hdc' bus='ide' tray='open'/>
<readonly/>
</disk>
+ <disk type='network' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source protocol="ftps" name="url_path">
+ <host name="hostname" port="990"/>
+ </source>
+ <target dev='hdc' bus='ide' tray='open'/>
+ <readonly/>
+ </disk>
<disk type='block' device='lun'>
<driver name='qemu' type='raw'/>
<source dev='/dev/sda'/>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 2f91f0f..2da3669 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1233,6 +1233,7 @@
<value>http</value>
<value>https</value>
<value>ftp</value>
+ <value>ftps</value>
</choice>
</attribute>
<optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 04563f6..ff3da7a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -266,7 +266,8 @@ VIR_ENUM_IMPL(virDomainDiskProtocol, VIR_DOMAIN_DISK_PROTOCOL_LAST,
"iscsi",
"http",
"https",
- "ftp")
+ "ftp",
+ "ftps")
VIR_ENUM_IMPL(virDomainDiskProtocolTransport, VIR_DOMAIN_DISK_PROTO_TRANS_LAST,
"tcp",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index d54b29e..ab1290b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -545,6 +545,7 @@ enum virDomainDiskProtocol {
VIR_DOMAIN_DISK_PROTOCOL_HTTP,
VIR_DOMAIN_DISK_PROTOCOL_HTTPS,
VIR_DOMAIN_DISK_PROTOCOL_FTP,
+ VIR_DOMAIN_DISK_PROTOCOL_FTPS,
VIR_DOMAIN_DISK_PROTOCOL_LAST
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 883b513..1bde013 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3917,6 +3917,12 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
disk->hosts->port ? disk->hosts->port : "21");
virBufferEscape(&opt, ',', ",", "%s,", disk->src);
break;
+ case VIR_DOMAIN_DISK_PROTOCOL_FTPS:
+ virBufferAsprintf(&opt, "file=ftps://%s:%s",
+ disk->hosts->name,
+ disk->hosts->port ? disk->hosts->port : "990");
+ virBufferEscape(&opt, ',', ",", "%s,", disk->src);
+ break;
}
} else if (disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME) {
if (qemuBuildVolumeString(conn, disk, &opt) < 0)
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.args
new file mode 100644
index 0000000..78dbff2
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.args
@@ -0,0 +1,8 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/kvm -S \
+-M pc-1.2 -m 1024 -smp 1 -nographic -nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait -boot d -usb \
+-drive \
+file=ftps://host.name:990/url/path/file.iso,if=none,media=cdrom,id=drive-ide0-1-0 \
+-device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.xml
new file mode 100644
index 0000000..b4a0f52
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.xml
@@ -0,0 +1,37 @@
+<domain type='kvm'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-1.2'>hvm</type>
+ <boot dev='cdrom'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/bin/kvm</emulator>
+ <disk type='network' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source protocol='ftps' name='/url/path/file.iso'>
+ <host name='host.name' port='990'/>
+ </source>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ <alias name='ide0-1-0'/>
+ <address type='drive' controller='0' bus='1' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index a11c9a8..5daee82 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -449,6 +449,8 @@ mymain(void)
QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-network-ftp", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE,
QEMU_CAPS_DRIVE);
+ DO_TEST("disk-cdrom-network-ftps", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE,
+ QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-empty", QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-tray",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_VIRTIO_TX_ALG);
--
1.7.9.5
1
0
Hello,
In the recent months various new methods were added to libvirt-java
which we (Apache CloudStack) would like to use in our KVM code.
For example resizing storage volumes, right now we have to do this with
Bash scripting since although libvirt supports resizing volumes, the
current release (0.4.9) of libvirt-java doesn't.
I don't know if there are any objections, but if possible I'd like to
see 0.5.0 released so we get this new functionality for CloudStack.
We use maven for building CloudStack and it fetches libvirt-java from
libvirt.org/maven2
Thank you,
Wido den Hollander
2
14
17 Sep '13
From: Aline Manera <alinefm(a)br.ibm.com>
qemu/KVM also supports https, ftps and tftp URL for cdrom definition.
With this patchset we will support all the protocols supported by qemu/KVM.
Aline Manera (3):
Add https protocol support for cdrom disk
Add ftps protocol support for cdrom disk
Add tftp protocol support for cdrom disk
docs/formatdomain.html.in | 24 +++++++++++++
docs/schemas/domaincommon.rng | 3 ++
src/conf/domain_conf.c | 5 ++-
src/conf/domain_conf.h | 3 ++
src/qemu/qemu_command.c | 18 ++++++++++
.../qemuxml2argv-disk-cdrom-network-ftps.args | 8 +++++
.../qemuxml2argv-disk-cdrom-network-ftps.xml | 37 ++++++++++++++++++++
.../qemuxml2argv-disk-cdrom-network-https.args | 8 +++++
.../qemuxml2argv-disk-cdrom-network-https.xml | 37 ++++++++++++++++++++
.../qemuxml2argv-disk-cdrom-network-tftp.args | 7 ++++
.../qemuxml2argv-disk-cdrom-network-tftp.xml | 37 ++++++++++++++++++++
tests/qemuxml2argvtest.c | 6 ++++
12 files changed, 192 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.xml
--
1.7.10.4
2
4
hi friends,
I need some help for finding python APIs of libvirt. I have already find the Java APIs doc at here:http://libvirt.org/sources/java/javadoc/, is there any doc just like this to make me to find APIs more easy. many thanks!!
tony gong
2
1
[libvirt] [PATCH 00/14] Add ability to handle the <metadata> element using the API
by Peter Krempa 17 Sep '13
by Peter Krempa 17 Sep '13
17 Sep '13
This series adds the initialy omitted functionality of changing the <metadata>
element using the virDomain[Get|Set]Metadata API.
First few patches are cleanup of some code noticed during implementation of the
other stuff.
Peter Krempa (14):
virsh-domain: Remove spurious ATTRIBUTE_UNUSED from cmdDesc
virsh-domain: Line up signal names array
qemu: Factor out body of qemuDomainGetMetadata for universal use
qemu: Factor out body of qemuDomainSetMetadata for universal use
conf: Factor out setting of metadata to simplify code
util: Add helper to convert libxml2 nodes to a string
virsh-domain: use virXMLNodeDump instead of xmlNodeDump
virsh-domain: Add command to allow modifications of XML metadata
conf: Add support for requesting of XML metadata via the API
conf: allow to add XML metadata using the virDomainSetMetadata api
lib: Don't force the key argument when deleting metadata
lxc: Add metadata modification APIs
test: Add <metadata> support into the test driver
tests: Add metadata tests
src/conf/domain_conf.c | 171 ++++++++++++++++++++++++++
src/conf/domain_conf.h | 17 +++
src/libvirt.c | 3 +-
src/libvirt_private.syms | 4 +
src/lxc/lxc_driver.c | 70 +++++++++++
src/qemu/qemu_driver.c | 122 ++-----------------
src/test/test_driver.c | 68 +++++++++++
src/util/virxml.c | 187 +++++++++++++++++++++++++++++
src/util/virxml.h | 13 ++
tests/Makefile.am | 7 ++
tests/metadatatest.c | 245 ++++++++++++++++++++++++++++++++++++++
tools/virsh-domain.c | 304 ++++++++++++++++++++++++++++++++---------------
12 files changed, 1001 insertions(+), 210 deletions(-)
create mode 100644 tests/metadatatest.c
--
1.8.3.2
2
32
Hi guys,
I made a automated test for the libvirt code in git source repository right now, It reported a check error.
The operation steps and error info are as following:
ubuntu@ubuntu:~/github/libvirt.git$ ./autogen.sh
ubuntu@ubuntu:~/github/libvirt.git$ ./configure --enable-werror
ubuntu@ubuntu:~/github/libvirt.git$ make check
............
make check-local
make[3]: Entering directory `/home/ubuntu/github/libvirt.git/daemon'
GEN check-augeas
make[3]: Leaving directory `/home/ubuntu/github/libvirt.git/daemon'
make[2]: Leaving directory `/home/ubuntu/github/libvirt.git/daemon'
make[1]: Leaving directory `/home/ubuntu/github/libvirt.git/daemon'
Making check in tools
make[1]: Entering directory `/home/ubuntu/github/libvirt.git/tools'
GEN libvirt-guests.sh
make check-am
make[2]: Entering directory `/home/ubuntu/github/libvirt.git/tools'
CC virsh-virsh.o
CC virsh-virsh-console.o
CC virsh-virsh-domain.o
virsh-domain.c: In function 'cmdMetadata':
virsh-domain.c:6857:10: error: declaration of 'remove' shadows a global declaration [-Werror=shadow]
cc1: all warnings being treated as errors
make[2]: *** [virsh-virsh-domain.o] Error 1
make[2]: Leaving directory `/home/ubuntu/github/libvirt.git/tools'
make[1]: *** [check] Error 2
make[1]: Leaving directory `/home/ubuntu/github/libvirt.git/tools'
make: *** [check-recursive] Error 1
What's the problem? Thanks.
BTW, The code version is:
ubuntu@ubuntu:~/github/libvirt.git$ git branch -a -v
* master 7655ed0 conf: Don't corrupt metadata on OOM
remotes/origin/HEAD -> origin/master
remotes/origin/master 7655ed0 conf: Don't corrupt metadata on OOM
------------------
Best regards!
GuanQiang
2013-09-17
3
4
Some people reported a few issues on different systems/compilers.
Series pushed under the build-breaker rule.
Peter Krempa (2):
conf: Avoid false positive of uninitialized variable use
virsh: Don't shadow global variable "remove" in cmdMetadata
src/conf/domain_conf.c | 9 +++------
tools/virsh-domain.c | 6 +++---
2 files changed, 6 insertions(+), 9 deletions(-)
--
1.8.3.2
1
2