[libvirt] [libvirt-glib] Distribute and install forgotten qemu-usb.xml
by Zeeshan Ali (Khattak)
From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
---
data/devices/Makefile.am | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/data/devices/Makefile.am b/data/devices/Makefile.am
index 17fbf17..f36cd8f 100644
--- a/data/devices/Makefile.am
+++ b/data/devices/Makefile.am
@@ -1,5 +1,5 @@
databasedir = $(pkgdatadir)/data/devices/
-database_DATA = xen.xml qemu-pci.xml virtio-pci.xml
+database_DATA = xen.xml qemu-pci.xml qemu-usb.xml qemu-ps2.xml virtio-pci.xml
EXTRA_DIST = $(database_DATA)
--
1.7.7.4
12 years, 11 months
[libvirt] [libvirt-glib] Fix gvir_config_domain_sound_set_model
by Christophe Fergeau
It's creating an unwanted extra <sound> XML node:
<sound>
<sound model="xxx">
</sound>
instead of the correct
<sound model="xxx">
---
libvirt-gconfig/libvirt-gconfig-domain-sound.c | 8 +-------
1 files changed, 1 insertions(+), 7 deletions(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-sound.c b/libvirt-gconfig/libvirt-gconfig-domain-sound.c
index 0812d06..abf9a14 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-sound.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-sound.c
@@ -72,15 +72,9 @@ GVirConfigDomainSound *gvir_config_domain_sound_new_from_xml(const gchar *xml,
void gvir_config_domain_sound_set_model(GVirConfigDomainSound *sound,
GVirConfigDomainSoundModel model)
{
- GVirConfigObject *node;
-
g_return_if_fail(GVIR_IS_CONFIG_DOMAIN_SOUND(sound));
- node = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(sound),
- "sound");
- g_return_if_fail(GVIR_IS_CONFIG_OBJECT(node));
- gvir_config_object_set_attribute_with_type(node, "model",
+ gvir_config_object_set_attribute_with_type(GVIR_CONFIG_OBJECT(sound), "model",
GVIR_TYPE_CONFIG_DOMAIN_SOUND_MODEL,
model,
NULL);
- g_object_unref(G_OBJECT(node));
}
--
1.7.7.4
12 years, 11 months
[libvirt] [test-API][PATCH] Update 2 functions for wrapped libs
by Nan Zhang
* lib/nodedevAPI.py: remove non-existent function ref()
* lib/secretAPI.py: fix case sensitive error on function name UUID()
---
lib/nodedevAPI.py | 9 ---------
lib/secretAPI.py | 2 +-
2 files changed, 1 insertions(+), 10 deletions(-)
diff --git a/lib/nodedevAPI.py b/lib/nodedevAPI.py
index cc96909..64fc4b8 100644
--- a/lib/nodedevAPI.py
+++ b/lib/nodedevAPI.py
@@ -137,15 +137,6 @@ class NodedevAPI:
code = e.get_error_code()
raise exception.LibvirtAPI(message, code)
- def ref(self, name):
- try:
- obj = self.lookup_by_name(name)
- obj.ref()
- except libvirt.libvirtError, e:
- message = e.get_error_message()
- code = e.get_error_code()
- raise exception.LibvirtAPI(message, code)
-
def get_name(self, obj):
try:
device_name = obj.name()
diff --git a/lib/secretAPI.py b/lib/secretAPI.py
index 876d22d..4aac27f 100644
--- a/lib/secretAPI.py
+++ b/lib/secretAPI.py
@@ -84,7 +84,7 @@ class SecretAPI(object):
def get_uuid(self, uuidstr):
try:
secret_obj = self.get_secret_by_uuid_string(uuidstr)
- return secret_obj.uuid()
+ return secret_obj.UUID()
except libvirt.libvirtError, e:
message = e.get_error_message()
code = e.get_error_code()
--
1.7.4.4
12 years, 11 months
[libvirt] question on kvm
by hero
hello everyone:
during the days I use kvm,I have got some questions I want to know,please read the following questions.
1.When a kvm VM is running, I use 'virsh setvcpus <domain> <count>' to change the cpu numbers of the VM, and when I use 'virsh dumpxml <domain>',there is a change from '<vcpus>count</vcpus>' to '<vcpus current="currentcount">count</vcpus>', just because of this I can't start the VM after I shutdown it. could you help me about this.
2. when I use "virsh setmaxmem <domain> <value>" to change the max memory of the kvm VM, it says "error: Unable to change MaxMemorySize
error: this function is not supported by the connection driver: virDomainSetMaxMemory", I want to know if libvirt has bugs or not.
3.It works fine except I reboot the VM after I use "virsh setmem <domain> <value>" to change the kvm VM boot memory, for example, I change the memory 3000000k, but it can not save the value the next time to reboot.
Best wishes and Merry Christmas!
SunYongGang
12 years, 11 months
[libvirt] [PATCH] tests: run schema checks in sorted order
by Eric Blake
Having a test that depends on file system timestamps and/or inode
allocation order is non-deterministic in its output.
* tests/schematestutils.sh: Run test in deterministic order.
---
Pushing under the trivial rule. Evidence of the non-determinism
can be found at the location of the three failures reported here:
https://www.redhat.com/archives/libvir-list/2011-December/msg00908.html
tests/schematestutils.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tests/schematestutils.sh b/tests/schematestutils.sh
index f2b3b50..ec6452a 100644
--- a/tests/schematestutils.sh
+++ b/tests/schematestutils.sh
@@ -13,7 +13,7 @@ for dir in $DIRS
do
XML=`find $abs_srcdir/$dir -name '*.xml'` || exit 1
- for xml in $XML
+ for xml in `echo $XML | sort`
do
n=`expr $n + 1`
cmd="xmllint --relaxng $SCHEMA --noout $xml"
--
1.7.7.4
12 years, 11 months
[libvirt] [PATCH] qemu: Support for overriding NOFILE limit
by Michal Privoznik
This patch adds max_files option to qemu.conf which can be used to
override system default limit on number of opened files that are
allowed for qemu user.
---
src/qemu/libvirtd_qemu.aug | 1 +
src/qemu/qemu.conf | 4 +++-
src/qemu/qemu_conf.c | 4 ++++
src/qemu/qemu_conf.h | 1 +
src/qemu/qemu_process.c | 16 ++++++++++++++--
src/qemu/test_libvirtd_qemu.aug | 4 ++++
6 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
index ad34e42..078e9c4 100644
--- a/src/qemu/libvirtd_qemu.aug
+++ b/src/qemu/libvirtd_qemu.aug
@@ -50,6 +50,7 @@ module Libvirtd_qemu =
| bool_entry "allow_disk_format_probing"
| bool_entry "set_process_name"
| int_entry "max_processes"
+ | int_entry "max_files"
| str_entry "lock_manager"
| int_entry "max_queued"
| int_entry "keepalive_interval"
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index c3f264f..6125d3b 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -301,9 +301,11 @@
# If max_processes is set to a positive integer, libvirt will use it to set
# maximum number of processes that can be run by qemu user. This can be used to
-# override default value set by host OS.
+# override default value set by host OS. The same apply to max_files which
+# set limit to maximum number of opened files.
#
# max_processes = 0
+# max_files = 0
# To enable 'Sanlock' project based locking of the file
# content (to prevent two VMs writing to the same
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 3766119..bc0a646 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -443,6 +443,10 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
CHECK_TYPE("max_processes", VIR_CONF_LONG);
if (p) driver->maxProcesses = p->l;
+ p = virConfGetValue(conf, "max_files");
+ CHECK_TYPE("max_files", VIR_CONF_LONG);
+ if (p) driver->maxFiles = p->l;
+
p = virConfGetValue (conf, "lock_manager");
CHECK_TYPE ("lock_manager", VIR_CONF_STRING);
if (p && p->str) {
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 8161269..f5a0f60 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -105,6 +105,7 @@ struct qemud_driver {
unsigned int setProcessName : 1;
int maxProcesses;
+ int maxFiles;
int max_queued;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 9123f4c..105b895 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2166,9 +2166,9 @@ qemuProcessPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
static int
qemuProcessLimits(struct qemud_driver *driver)
{
- if (driver->maxProcesses > 0) {
- struct rlimit rlim;
+ struct rlimit rlim;
+ if (driver->maxProcesses > 0) {
rlim.rlim_cur = rlim.rlim_max = driver->maxProcesses;
if (setrlimit(RLIMIT_NPROC, &rlim) < 0) {
virReportSystemError(errno,
@@ -2178,6 +2178,18 @@ qemuProcessLimits(struct qemud_driver *driver)
}
}
+ if (driver->maxFiles > 0) {
+ /* Max number of opened files is one greater than
+ * actual limit. See man setrlimit */
+ rlim.rlim_cur = rlim.rlim_max = driver->maxFiles + 1;
+ if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
+ virReportSystemError(errno,
+ _("cannot set max opened files to %d"),
+ driver->maxFiles);
+ return -1;
+ }
+ }
+
return 0;
}
diff --git a/src/qemu/test_libvirtd_qemu.aug b/src/qemu/test_libvirtd_qemu.aug
index f7476ae..f841936 100644
--- a/src/qemu/test_libvirtd_qemu.aug
+++ b/src/qemu/test_libvirtd_qemu.aug
@@ -114,6 +114,8 @@ vnc_auto_unix_socket = 1
max_processes = 12345
+max_files = 67890
+
lock_manager = \"fcntl\"
keepalive_interval = 1
@@ -242,6 +244,8 @@ keepalive_count = 42
{ "#empty" }
{ "max_processes" = "12345" }
{ "#empty" }
+{ "max_files" = "67890" }
+{ "#empty" }
{ "lock_manager" = "fcntl" }
{ "#empty" }
{ "keepalive_interval" = "1" }
--
1.7.3.4
12 years, 11 months
[libvirt] [PATCH v2] virsh: Add two new commands to change media
by Osier Yang
eject-media to eject the media from, and insert-media to insert
media into CDROM or floppy drive.
---
Basically this patch is just rebaing of
https://www.redhat.com/archives/libvir-list/2011-June/msg01516.html,
with a bit improvement, as I explained in the mail thread, we
don't have to wait for the new QEMU monitor commands, what we
need is just separate the tray and media management in virsh,
if one day QEMU gets the patch for those new commands pushed,
we can switch to honor them easily (regardless of whether we do
it inside updateDeviceFlags API or in new APIs).
---
tools/virsh.c | 369 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
tools/virsh.pod | 33 +++++
2 files changed, 402 insertions(+), 0 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 02f2e0d..228a9dc 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -13453,6 +13453,373 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
}
/*
+ * "eject-media" command
+ */
+static const vshCmdInfo info_eject_media[] = {
+ {"help", N_("eject media from CD or floppy drive")},
+ {"desc", N_("Eject media from CD or floppy drive.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_eject_media[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
+ {"target", VSH_OT_DATA, VSH_OFLAG_REQ, N_("target of disk device")},
+ {"current", VSH_OT_BOOL, 0, N_("can be either or both of --live and --config, "
+ "depends on implementation of hypervisor driver")},
+ {"live", VSH_OT_BOOL, 0, N_("alter live configuration of running domain")},
+ {"config", VSH_OT_BOOL, 0, N_("alter persistent configuration, effect observed on next boot")},
+ {"force", VSH_OT_BOOL, 0, N_("force media ejection")},
+ {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdEjectMedia(vshControl *ctl, const vshCmd *cmd)
+{
+ xmlDocPtr xml = NULL;
+ xmlXPathObjectPtr obj=NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ xmlNodePtr cur = NULL;
+ xmlBufferPtr xml_buf = NULL;
+ virDomainPtr dom = NULL;
+ const char *target = NULL;
+ char *doc;
+ int i = 0, diff_tgt;
+ int ret;
+ bool functionReturn = false;
+ int flags = 0;
+ int config = vshCommandOptBool(cmd, "config");
+ int live = vshCommandOptBool(cmd, "live");
+ int current = vshCommandOptBool(cmd, "current");
+ int force = vshCommandOptBool(cmd, "force");
+ bool has_source = false;
+
+ if (current) {
+ if (live || config) {
+ vshError(ctl, "%s", _("--current must be specified exclusively"));
+ return false;
+ }
+ flags = VIR_DOMAIN_AFFECT_CURRENT;
+ } else {
+ if (config)
+ flags |= VIR_DOMAIN_AFFECT_CONFIG;
+ if (live)
+ flags |= VIR_DOMAIN_AFFECT_LIVE;
+ }
+
+ if (force)
+ flags |= VIR_DOMAIN_DEVICE_MODIFY_FORCE;
+
+ if (!vshConnectionUsability(ctl, ctl->conn))
+ goto cleanup;
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+ goto cleanup;
+
+ if (vshCommandOptString(cmd, "target", &target) <= 0)
+ goto cleanup;
+
+ if (flags & VIR_DOMAIN_AFFECT_CONFIG)
+ doc = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE);
+ else
+ doc = virDomainGetXMLDesc(dom, 0);
+ if (!doc)
+ goto cleanup;
+
+ xml = xmlReadDoc((const xmlChar *) doc, "domain.xml", NULL,
+ XML_PARSE_NOENT | XML_PARSE_NONET |
+ XML_PARSE_NOWARNING);
+ VIR_FREE(doc);
+ if (!xml) {
+ vshError(ctl, "%s", _("Failed to get disk information"));
+ goto cleanup;
+ }
+ ctxt = xmlXPathNewContext(xml);
+ if (!ctxt) {
+ vshError(ctl, "%s", _("Failed to get disk information"));
+ goto cleanup;
+ }
+
+ obj = xmlXPathEval(BAD_CAST "/domain/devices/disk", ctxt);
+ if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
+ (obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0)) {
+ vshError(ctl, "%s", _("Failed to get disk information"));
+ goto cleanup;
+ }
+
+ /* search target */
+ for (; i < obj->nodesetval->nodeNr; i++) {
+ xmlNodePtr n = obj->nodesetval->nodeTab[i];
+ bool is_supported = false;
+
+ /* Check if the disk is CDROM or floppy disk */
+ if (xmlStrEqual(n->name, BAD_CAST "disk")) {
+ char *device_value = virXMLPropString(n, "device");
+
+ if (STREQ(device_value, "cdrom") ||
+ STREQ(device_value, "floppy"))
+ is_supported = true;
+
+ VIR_FREE(device_value);
+ }
+
+ cur = obj->nodesetval->nodeTab[i]->children;
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "target")) {
+ char *tmp_tgt = virXMLPropString(cur, "dev");
+
+ diff_tgt = STREQ(tmp_tgt, target);
+ VIR_FREE(tmp_tgt);
+
+ if (diff_tgt && is_supported) {
+ goto hit;
+ }
+ }
+
+ cur = cur->next;
+ }
+ }
+ vshError(ctl, _("No found CDROM or floppy disk whose target is %s"), target);
+ goto cleanup;
+
+ hit:
+ xml_buf = xmlBufferCreate();
+ if (!xml_buf) {
+ vshError(ctl, "%s", _("Failed to allocate memory"));
+ goto cleanup;
+ }
+
+ cur = obj->nodesetval->nodeTab[i]->children;
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "source")) {
+ xmlUnlinkNode(cur);
+ xmlFreeNode(cur);
+ has_source = true;
+ break;
+ }
+
+ cur = cur->next;
+ }
+
+ if (!has_source) {
+ vshError(ctl, _("The disk device whose target is '%s' doesn't "
+ "have media"), target);
+ goto cleanup;
+ }
+
+ if (xmlNodeDump(xml_buf, xml, obj->nodesetval->nodeTab[i], 0, 0) < 0) {
+ vshError(ctl, "%s", _("Failed to create XML"));
+ goto cleanup;
+ }
+
+ ret = virDomainUpdateDeviceFlags(dom, (char *)xmlBufferContent(xml_buf), flags);
+
+ if (ret != 0) {
+ vshError(ctl, "%s", _("Failed to eject media"));
+ } else {
+ vshPrint(ctl, "%s", _("Media ejected successfully\n"));
+ functionReturn = true;
+ }
+
+ cleanup:
+ xmlXPathFreeObject(obj);
+ xmlXPathFreeContext(ctxt);
+ xmlFreeDoc(xml);
+ xmlBufferFree(xml_buf);
+ if (dom)
+ virDomainFree(dom);
+ return functionReturn;
+}
+
+/*
+ * "insert-media" command
+ */
+static const vshCmdInfo info_insert_media[] = {
+ {"help", N_("insert media into CD or floppy drive")},
+ {"desc", N_("Insert media into CD or floppy drive.")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_insert_media[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
+ {"target", VSH_OT_DATA, VSH_OFLAG_REQ, N_("target of disk device")},
+ {"source", VSH_OT_DATA, VSH_OFLAG_REQ, N_("source of the media")},
+ {"current", VSH_OT_BOOL, 0, N_("can be either or both of --live and --config, "
+ "depends on implementation of hypervisor driver")},
+ {"live", VSH_OT_BOOL, 0, N_("alter live configuration of running domain")},
+ {"config", VSH_OT_BOOL, 0, N_("alter persistent configuration, effect observed on next boot")},
+ {"force", VSH_OT_BOOL, 0, N_("force media insertion")},
+ {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdInsertMedia(vshControl *ctl, const vshCmd *cmd)
+{
+ xmlDocPtr xml = NULL;
+ xmlXPathObjectPtr obj=NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ xmlNodePtr cur = NULL;
+ xmlNodePtr new_node = NULL;
+ xmlBufferPtr xml_buf = NULL;
+ virDomainPtr dom = NULL;
+ const char *target = NULL;
+ const char *source = NULL;
+ char *doc;
+ int i = 0, diff_tgt;
+ int ret;
+ bool functionReturn = false;
+ int flags = 0;
+ const char *disk_type = NULL;
+ int config = vshCommandOptBool(cmd, "config");
+ int live = vshCommandOptBool(cmd, "live");
+ int current = vshCommandOptBool(cmd, "current");
+ int force = vshCommandOptBool(cmd, "force");
+
+ if (current) {
+ if (live || config) {
+ vshError(ctl, "%s", _("--current must be specified exclusively"));
+ return false;
+ }
+ flags = VIR_DOMAIN_AFFECT_CURRENT;
+ } else {
+ if (config)
+ flags |= VIR_DOMAIN_AFFECT_CONFIG;
+ if (live)
+ flags |= VIR_DOMAIN_AFFECT_LIVE;
+ }
+
+ if (force)
+ flags |= VIR_DOMAIN_DEVICE_MODIFY_FORCE;
+
+ if (!vshConnectionUsability(ctl, ctl->conn))
+ goto cleanup;
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+ goto cleanup;
+
+ if (vshCommandOptString(cmd, "target", &target) <= 0)
+ goto cleanup;
+
+ if (vshCommandOptString(cmd, "source", &source) <= 0)
+ goto cleanup;
+
+ if (flags & VIR_DOMAIN_AFFECT_CONFIG)
+ doc = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE);
+ else
+ doc = virDomainGetXMLDesc(dom, 0);
+ if (!doc)
+ goto cleanup;
+
+ xml = xmlReadDoc((const xmlChar *) doc, "domain.xml", NULL,
+ XML_PARSE_NOENT | XML_PARSE_NONET |
+ XML_PARSE_NOWARNING);
+ VIR_FREE(doc);
+ if (!xml) {
+ vshError(ctl, "%s", _("Failed to get disk information"));
+ goto cleanup;
+ }
+ ctxt = xmlXPathNewContext(xml);
+ if (!ctxt) {
+ vshError(ctl, "%s", _("Failed to get disk information"));
+ goto cleanup;
+ }
+
+ obj = xmlXPathEval(BAD_CAST "/domain/devices/disk", ctxt);
+ if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
+ (obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0)) {
+ vshError(ctl, "%s", _("Failed to get disk information"));
+ goto cleanup;
+ }
+
+ /* search target */
+ for (; i < obj->nodesetval->nodeNr; i++) {
+ xmlNodePtr n = obj->nodesetval->nodeTab[i];
+ bool is_supported = false;
+
+ /* Check if the disk is CDROM or floppy disk */
+ if (xmlStrEqual(n->name, BAD_CAST "disk")) {
+ disk_type = virXMLPropString(n, "type");
+ char *device_value = virXMLPropString(n, "device");
+
+ if (STREQ(device_value, "cdrom") ||
+ STREQ(device_value, "floppy"))
+ is_supported = true;
+
+ VIR_FREE(device_value);
+ }
+
+ cur = obj->nodesetval->nodeTab[i]->children;
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "target")) {
+ char *tmp_tgt = virXMLPropString(cur, "dev");
+
+ diff_tgt = STREQ(tmp_tgt, target);
+ VIR_FREE(tmp_tgt);
+
+ if (diff_tgt && is_supported) {
+ goto hit;
+ }
+ }
+
+ cur = cur->next;
+ }
+ VIR_FREE(disk_type);
+ }
+ vshError(ctl, _("No found CDROM or floppy disk whose target is %s"), target);
+ goto cleanup;
+
+ hit:
+ xml_buf = xmlBufferCreate();
+ if (!xml_buf) {
+ vshError(ctl, "%s", _("Failed to allocate memory"));
+ goto cleanup;
+ }
+
+ cur = obj->nodesetval->nodeTab[i]->children;
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "source")) {
+ vshError(ctl, _("The disk device whose target is '%s' has media, "
+ "you may need to eject it first"), target);
+ goto cleanup;
+ }
+
+ cur = cur->next;
+ }
+
+ /* Insert node <source> */
+ new_node = xmlNewNode(NULL, BAD_CAST "source");
+ xmlNewProp(new_node, (const xmlChar *)disk_type, (const xmlChar *)source);
+ VIR_FREE(disk_type);
+ xmlAddChild(obj->nodesetval->nodeTab[i], new_node);
+
+ if (xmlNodeDump(xml_buf, xml, obj->nodesetval->nodeTab[i], 0, 0) < 0) {
+ vshError(ctl, "%s", _("Failed to create XML"));
+ goto cleanup;
+ }
+
+ ret = virDomainUpdateDeviceFlags(dom, (char *)xmlBufferContent(xml_buf), flags);
+
+ if (ret != 0) {
+ vshError(ctl, "%s", _("Failed to insert media"));
+ } else {
+ vshPrint(ctl, "%s", _("Media inserted successfully\n"));
+ functionReturn = true;
+ }
+
+ cleanup:
+ xmlXPathFreeObject(obj);
+ xmlXPathFreeContext(ctxt);
+ xmlFreeDoc(xml);
+ xmlBufferFree(xml_buf);
+ if (dom)
+ virDomainFree(dom);
+ return functionReturn;
+}
+
+/*
* "detach-disk" command
*/
static const vshCmdInfo info_detach_disk[] = {
@@ -15600,7 +15967,9 @@ static const vshCmdDef domManagementCmds[] = {
{"dump", cmdDump, opts_dump, info_dump, 0},
{"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml, 0},
{"edit", cmdEdit, opts_edit, info_edit, 0},
+ {"eject-media", cmdEjectMedia, opts_eject_media, info_eject_media, 0},
{"inject-nmi", cmdInjectNMI, opts_inject_nmi, info_inject_nmi, 0},
+ {"insert-media", cmdInsertMedia, opts_insert_media, info_insert_media, 0},
{"send-key", cmdSendKey, opts_send_key, info_send_key},
{"managedsave", cmdManagedSave, opts_managedsave, info_managedsave, 0},
{"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove,
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 6c10245..45a3fde 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1387,6 +1387,39 @@ option can be used to force device update, e.g., to eject a CD-ROM even if it
is locked/mounted in the domain. See the documentation to learn about libvirt
XML format for a device.
+=item B<eject-media> I<domain-id> I<target> [I<--current>] [I<--live>]
+[I<--config>] [I<--force>]
+
+Eject media from CD or floppy drive. The I<target> is the device as seen
+from the domain.
+
+If I<--live> is specified, alter live configuration of running guest.
+If I<--config> is specified, alter persistent configuration, effect observed
+on next boot.
+I<--current> can be either or both of I<live> and I<config>, depends on
+the hypervisor's implementation.
+Both I<--live> and I<--config> flags may be given, but I<--current> is
+exclusive. If no flag is specified, behavior is different depending
+on hypervisor.
+The I<--force> option can be used to force media ejection.
+
+=item B<insert-media> I<domain-id> I<target> I<source> [I<--current>]
+[I<--live>] [I<--config>] [I<--force>]
+
+Insert media into CD or floppy drive. The I<target> is the device as seen
+from the domain. The I<source> specifies the path of the media which is to
+be inserted.
+
+If I<--live> is specified, alter live configuration of running guest.
+If I<--config> is specified, alter persistent configuration, effect observed
+on next boot.
+I<--current> can be either or both of I<live> and I<config>, depends on
+the hypervisor's implementation.
+Both I<--live> and I<--config> flags may be given, but I<--current> is
+exclusive. If no flag is specified, behavior is different depending
+on hypervisor.
+The I<--force> option can be used to force media ejection.
+
=back
=head1 NODEDEV COMMANDS
--
1.7.7.3
12 years, 11 months
[libvirt] [PATCH] qemu: Support copy on read for disk
by Osier Yang
Upstream QEMU supports it since commit fb0490f69.
---
docs/formatdomain.html.in | 9 +++++++++
docs/schemas/domaincommon.rng | 11 +++++++++++
src/conf/domain_conf.c | 24 +++++++++++++++++++++++-
src/conf/domain_conf.h | 10 ++++++++++
src/libvirt_private.syms | 2 ++
src/qemu/qemu_capabilities.c | 3 +++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 11 +++++++++++
8 files changed, 70 insertions(+), 1 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 9cf0f12..779317f 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1187,6 +1187,15 @@
<b>In general you should leave this option alone, unless you
are very certain you know what you are doing.</b>
</li>
+ <li>
+ The optional <code>copy_on_read</code> attribute controls
+ wether to copy read backing file into the image file. The
+ value can be either "on" or "off".
+ Copy-on-read avoids accessing the same backing file sectors
+ repeatedly and is useful when the backing file is over a slow
+ network. By default copy-on-read is off.
+ <span class='since'>Since 0.9.9 (QEMU and KVM only)</span>
+ </li>
</ul>
</dd>
<dt><code>boot</code></dt>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 553a6f0..b511ec2 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -959,6 +959,14 @@
</choice>
</attribute>
</define>
+ <define name="copy_on_read">
+ <attribute name='copy_on_read'>
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </attribute>
+ </define>
<define name="controller">
<element name="controller">
<choice>
@@ -1308,6 +1316,9 @@
<optional>
<ref name="event_idx"/>
</optional>
+ <optional>
+ <ref name="copy_on_read"/>
+ </optional>
<empty/>
</element>
</optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2897b4a..a51eb40 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -208,6 +208,11 @@ VIR_ENUM_IMPL(virDomainVirtioEventIdx, VIR_DOMAIN_VIRTIO_EVENT_IDX_LAST,
"on",
"off")
+VIR_ENUM_IMPL(virDomainDiskCopyOnRead, VIR_DOMAIN_DISK_COPY_ON_READ_LAST,
+ "default",
+ "on",
+ "off")
+
VIR_ENUM_IMPL(virDomainDiskSnapshot, VIR_DOMAIN_DISK_SNAPSHOT_LAST,
"default",
"no",
@@ -2621,6 +2626,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
char *iotag = NULL;
char *ioeventfd = NULL;
char *event_idx = NULL;
+ char *copy_on_read = NULL;
char *devaddr = NULL;
virStorageEncryptionPtr encryption = NULL;
char *serial = NULL;
@@ -2749,6 +2755,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
iotag = virXMLPropString(cur, "io");
ioeventfd = virXMLPropString(cur, "ioeventfd");
event_idx = virXMLPropString(cur, "event_idx");
+ copy_on_read = virXMLPropString(cur, "copy_on_read");
} else if (xmlStrEqual(cur->name, BAD_CAST "auth")) {
authUsername = virXMLPropString(cur, "username");
if (authUsername == NULL) {
@@ -3053,6 +3060,17 @@ virDomainDiskDefParseXML(virCapsPtr caps,
def->event_idx = idx;
}
+ if (copy_on_read) {
+ int cor;
+ if ((cor = virDomainDiskCopyOnReadTypeFromString(copy_on_read)) <= 0) {
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown disk copy_on_read mode '%s'"),
+ copy_on_read);
+ goto error;
+ }
+ def->copy_on_read = cor;
+ }
+
if (devaddr) {
if (virDomainParseLegacyDeviceAddress(devaddr,
&def->info.addr.pci) < 0) {
@@ -3146,6 +3164,7 @@ cleanup:
VIR_FREE(iotag);
VIR_FREE(ioeventfd);
VIR_FREE(event_idx);
+ VIR_FREE(copy_on_read);
VIR_FREE(devaddr);
VIR_FREE(serial);
virStorageEncryptionFree(encryption);
@@ -9768,6 +9787,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
const char *iomode = virDomainDiskIoTypeToString(def->iomode);
const char *ioeventfd = virDomainIoEventFdTypeToString(def->ioeventfd);
const char *event_idx = virDomainVirtioEventIdxTypeToString(def->event_idx);
+ const char *copy_on_read = virDomainVirtioEventIdxTypeToString(def->copy_on_read);
const char *startupPolicy = virDomainStartupPolicyTypeToString(def->startupPolicy);
char uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -9808,7 +9828,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferAddLit(buf, ">\n");
if (def->driverName || def->driverType || def->cachemode ||
- def->ioeventfd || def->event_idx) {
+ def->ioeventfd || def->event_idx || def->copy_on_read) {
virBufferAddLit(buf, " <driver");
if (def->driverName)
virBufferAsprintf(buf, " name='%s'", def->driverName);
@@ -9826,6 +9846,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, " ioeventfd='%s'", ioeventfd);
if (def->event_idx)
virBufferAsprintf(buf, " event_idx='%s'", event_idx);
+ if (def->copy_on_read)
+ virBufferAsprintf(buf, " copy_on_read='%s'", copy_on_read);
virBufferAddLit(buf, "/>\n");
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 1f6e442..4575ab2 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -288,6 +288,14 @@ enum virDomainVirtioEventIdx {
VIR_DOMAIN_VIRTIO_EVENT_IDX_LAST
};
+enum virDomainDiskCopyOnRead {
+ VIR_DOMAIN_DISK_COPY_ON_READ_DEFAULT = 0,
+ VIR_DOMAIN_DISK_COPY_ON_READ_ON,
+ VIR_DOMAIN_DISK_COPY_ON_READ_OFF,
+
+ VIR_DOMAIN_DISK_COPY_ON_READ_LAST
+};
+
enum virDomainDiskSnapshot {
VIR_DOMAIN_DISK_SNAPSHOT_DEFAULT = 0,
VIR_DOMAIN_DISK_SNAPSHOT_NO,
@@ -363,6 +371,7 @@ struct _virDomainDiskDef {
int iomode;
int ioeventfd;
int event_idx;
+ int copy_on_read;
int snapshot; /* enum virDomainDiskSnapshot */
int startupPolicy; /* enum virDomainStartupPolicy */
unsigned int readonly : 1;
@@ -1968,6 +1977,7 @@ VIR_ENUM_DECL(virDomainDiskSecretType)
VIR_ENUM_DECL(virDomainDiskSnapshot)
VIR_ENUM_DECL(virDomainIoEventFd)
VIR_ENUM_DECL(virDomainVirtioEventIdx)
+VIR_ENUM_DECL(virDomainDiskCopyOnRead)
VIR_ENUM_DECL(virDomainController)
VIR_ENUM_DECL(virDomainControllerModelSCSI)
VIR_ENUM_DECL(virDomainControllerModelUSB)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4a86bdc..63c2947 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -290,6 +290,8 @@ virDomainDeviceTypeToString;
virDomainDiskBusTypeToString;
virDomainDiskCacheTypeFromString;
virDomainDiskCacheTypeToString;
+virDomainDiskCopyOnReadTypeFromString;
+virDomainDiskCopyOnReadTypeToString;
virDomainDiskDefAssignAddress;
virDomainDiskDefForeachPath;
virDomainDiskDefFree;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 43c7578..f32c792 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -144,6 +144,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"ich9-ahci",
"no-acpi",
"fsdev-readonly",
+ "drive-copy-on-read",
);
struct qemu_feature_flags {
@@ -1023,6 +1024,8 @@ qemuCapsComputeCmdFlags(const char *help,
qemuCapsSet(flags, QEMU_CAPS_DRIVE_READONLY);
if (strstr(help, "aio=threads|native"))
qemuCapsSet(flags, QEMU_CAPS_DRIVE_AIO);
+ if (strstr(help, "copy-on-read=on|off"))
+ qemuCapsSet(flags, QEMU_CAPS_DRIVE_COPY_ON_READ);
}
if ((p = strstr(help, "-vga")) && !strstr(help, "-std-vga")) {
const char *nl = strstr(p, "\n");
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index c759baf..38106dd 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -117,6 +117,7 @@ enum qemuCapsFlags {
QEMU_CAPS_ICH9_AHCI = 77, /* -device ich9-ahci */
QEMU_CAPS_NO_ACPI = 78, /* -no-acpi */
QEMU_CAPS_FSDEV_READONLY =79, /* -fsdev readonly supported */
+ QEMU_CAPS_DRIVE_COPY_ON_READ = 80, /* -drive copy-on-read */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index ea1b763..629f13d 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1926,6 +1926,17 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
virBufferAddLit(&opt, ",cache=off");
}
+ if (disk->copy_on_read) {
+ if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ)) {
+ virBufferAsprintf(&opt, ",copy-on-read=%s",
+ virDomainDiskCopyOnReadTypeToString(disk->copy_on_read));
+ } else {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("copy_on_read is not supported by this QEMU binary"));
+ goto error;
+ }
+ }
+
if (qemuCapsGet(qemuCaps, QEMU_CAPS_MONITOR_JSON)) {
const char *wpolicy = NULL, *rpolicy = NULL;
--
1.7.7.3
12 years, 11 months
[libvirt] [PATCH] qemuhelptest: Add new qemuCap flag
by Michal Privoznik
Latest patch a1a83c587443 introduces new qemu capability flag
QEMU_CAPS_FSDEV_READONLY. However, it was missing in qemuhelptest
making test for qemu-1.0 fail.
---
Pushing under build-breaker rule.
tests/qemuhelptest.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c
index f31c903..60155e7 100644
--- a/tests/qemuhelptest.c
+++ b/tests/qemuhelptest.c
@@ -647,7 +647,8 @@ mymain(void)
QEMU_CAPS_NO_SHUTDOWN,
QEMU_CAPS_PCI_ROMBAR,
QEMU_CAPS_ICH9_AHCI,
- QEMU_CAPS_NO_ACPI);
+ QEMU_CAPS_NO_ACPI,
+ QEMU_CAPS_FSDEV_READONLY);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
1.7.3.4
12 years, 11 months
[libvirt] [PATCH] Add new attribute writeout to <filesystem> element
by Deepak C Shetty
This introduces new attribute writeout with only supported
value as immediate. This will be an optional
attribute with no defaults. This helps specify whether
to skip the host page cache.
When writeout is specified, meaning when writeout=immediate
a writeback is explicitly initiated for the dirty pages in
the host page cache as part of the guest file write operation.
Usage:
<filesystem type='mount' accessmode='passthrough' writeout='immediate'>
<source dir='/export/to/guest'/>
<target dir='mount_tag'/>
</filesystem>
Currently this only works with type='mount' for the QEMU/KVM driver.
Signed-off-by: Deepak C Shetty <deepakcs(a)linux.vnet.ibm.com>
---
docs/formatdomain.html.in | 8 +++++++-
docs/schemas/domaincommon.rng | 5 +++++
src/conf/domain_conf.c | 29 +++++++++++++++++++++++++++--
src/conf/domain_conf.h | 10 ++++++++++
src/qemu/qemu_command.c | 9 +++++++++
5 files changed, 58 insertions(+), 3 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index c57b7b3..803db8e 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1303,7 +1303,7 @@
<source name='my-vm-template'/>
<target dir='/'/>
</filesystem>
- <filesystem type='mount' accessmode='passthrough'>
+ <filesystem type='mount' accessmode='passthrough' writeout='immediate'>
<driver type='path'/>
<source dir='/export/to/guest'/>
<target dir='/import/from/host'/>
@@ -1379,6 +1379,12 @@
</dd>
</dl>
+ The filesystem block has an optional attribute <code>writeout='immediate'</code>
+ to help specify whether to skip the host page cache. When writeout is specified, meaning when
+ writeout=immediate a writeback is explicitly initiated for the dirty pages in
+ the host page cache as part of the guest file write operation. When this attribute is not
+ specified, there are no defaults, meaning explicit writeback won't be initiated.
+
</dd>
<dt><code>source</code></dt>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 27ec1da..2298994 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1106,6 +1106,11 @@
<value>squash</value>
</choice>
</attribute>
+ <attribute name="writeout">
+ <choice>
+ <value>immediate</value>
+ </choice>
+ </attribute>
</optional>
</element>
</define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2c91f82..80b8eab 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -256,6 +256,9 @@ VIR_ENUM_IMPL(virDomainFSAccessMode, VIR_DOMAIN_FS_ACCESSMODE_LAST,
"mapped",
"squash")
+VIR_ENUM_IMPL(virDomainFSWriteout, VIR_DOMAIN_FS_WRITEOUT_LAST,
+ "default",
+ "immediate")
VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST,
"user",
@@ -3258,6 +3261,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
char *source = NULL;
char *target = NULL;
char *accessmode = NULL;
+ char *writeout = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@@ -3286,6 +3290,17 @@ virDomainFSDefParseXML(xmlNodePtr node,
def->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH;
}
+ writeout = virXMLPropString(node, "writeout");
+ if (writeout) {
+ if ((def->writeout = virDomainFSWriteoutTypeFromString(writeout)) < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unknown filesystem writeout '%s'"), writeout);
+ goto error;
+ }
+ } else {
+ def->writeout = VIR_DOMAIN_FS_WRITEOUT_DEFAULT;
+ }
+
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) {
@@ -3348,6 +3363,7 @@ cleanup:
VIR_FREE(target);
VIR_FREE(source);
VIR_FREE(accessmode);
+ VIR_FREE(writeout);
return def;
@@ -10006,6 +10022,7 @@ virDomainFSDefFormat(virBufferPtr buf,
const char *type = virDomainFSTypeToString(def->type);
const char *accessmode = virDomainFSAccessModeTypeToString(def->accessmode);
const char *fsdriver = virDomainFSDriverTypeTypeToString(def->fsdriver);
+ const char *writeout = virDomainFSWriteoutTypeToString(def->writeout);
if (!type) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -10022,12 +10039,20 @@ virDomainFSDefFormat(virBufferPtr buf,
if (def->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_PATH ||
def->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_DEFAULT) {
virBufferAsprintf(buf,
- " <filesystem type='%s' accessmode='%s'>\n",
+ " <filesystem type='%s' accessmode='%s'",
type, accessmode);
} else {
virBufferAsprintf(buf,
- " <filesystem type='%s'>\n", type);
+ " <filesystem type='%s'", type);
}
+
+ /* Dont generate anything if writeout is set to default */
+ if (def->writeout) {
+ virBufferAsprintf(buf, " writeout='%s'", writeout);
+ }
+
+ /* close the filesystem element */
+ virBufferAddLit(buf,">\n");
if (def->fsdriver) {
virBufferAsprintf(buf, " <driver type='%s'/>\n", fsdriver);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3229a6f..bf4d79b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -450,12 +450,21 @@ enum virDomainFSAccessMode {
VIR_DOMAIN_FS_ACCESSMODE_LAST
};
+/* Filesystem Writeout */
+enum virDomainFSWriteout {
+ VIR_DOMAIN_FS_WRITEOUT_DEFAULT = 0,
+ VIR_DOMAIN_FS_WRITEOUT_IMMEDIATE,
+
+ VIR_DOMAIN_FS_WRITEOUT_LAST
+};
+
typedef struct _virDomainFSDef virDomainFSDef;
typedef virDomainFSDef *virDomainFSDefPtr;
struct _virDomainFSDef {
int type;
int fsdriver;
int accessmode;
+ int writeout;
char *src;
char *dst;
unsigned int readonly : 1;
@@ -1973,6 +1982,7 @@ VIR_ENUM_DECL(virDomainControllerModelUSB)
VIR_ENUM_DECL(virDomainFS)
VIR_ENUM_DECL(virDomainFSDriverType)
VIR_ENUM_DECL(virDomainFSAccessMode)
+VIR_ENUM_DECL(virDomainFSWriteout)
VIR_ENUM_DECL(virDomainNet)
VIR_ENUM_DECL(virDomainNetBackend)
VIR_ENUM_DECL(virDomainNetVirtioTxMode)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1f70eb1..ccfd092 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -108,6 +108,10 @@ VIR_ENUM_IMPL(qemuDomainFSDriver, VIR_DOMAIN_FS_DRIVER_TYPE_LAST,
"local",
"handle");
+VIR_ENUM_DECL(qemuDomainFSWriteout)
+VIR_ENUM_IMPL(qemuDomainFSWriteout, VIR_DOMAIN_FS_WRITEOUT_LAST,
+ "default",
+ "immediate");
static void
uname_normalize (struct utsname *ut)
@@ -1990,6 +1994,7 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs,
{
virBuffer opt = VIR_BUFFER_INITIALIZER;
const char *driver = qemuDomainFSDriverTypeToString(fs->fsdriver);
+ const char *writeout = qemuDomainFSWriteoutTypeToString(fs->writeout);
if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
@@ -2014,6 +2019,10 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs,
virBufferAddLit(&opt, ",security_model=none");
}
}
+
+ if (fs->writeout != VIR_DOMAIN_FS_WRITEOUT_DEFAULT) {
+ virBufferAsprintf(&opt, ",writeout=%s", writeout);
+ }
virBufferAsprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
virBufferAsprintf(&opt, ",path=%s", fs->src);
12 years, 11 months