[libvirt] [PATCH] blockjob: Report correct error when missing qemu support
by Adam Litke
When executing blockjob monitor commands, we are not checking for
CommandNotFound errors. This results in 'unexpected error' messages when using
a qemu without support for the required commands. Fix this up by checking for
CommandNotFound errors for QMP and detecting this condition for the text
monitor.
This fixes the problem reported in Bug 727502.
Signed-off-by: Adam Litke <agl(a)us.ibm.com>
---
src/qemu/qemu_monitor_json.c | 3 +++
src/qemu/qemu_monitor_text.c | 20 ++++++++++++++++++++
2 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 7adfb26..4c8a08b 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2939,6 +2939,9 @@ int qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
else if (qemuMonitorJSONHasError(reply, "NotSupported"))
qemuReportError(VIR_ERR_OPERATION_INVALID,
_("Operation is not supported for device: %s"), device);
+ else if (qemuMonitorJSONHasError(reply, "CommandNotFound"))
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Operation is not supported"));
else
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unexpected error"));
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 52d924a..d9cad2d 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -271,6 +271,19 @@ qemuMonitorTextCommandWithFd(qemuMonitorPtr mon,
scm_fd, reply);
}
+/* Check monitor output for evidence that the command was not recognized.
+ * For 'info' commands, qemu returns help text. For other commands, qemu
+ * returns 'unknown command:'.
+ */
+static int
+qemuMonitorTextCommandNotFound(const char *reply)
+{
+ if (strstr(reply, "unknown command:"))
+ return 1;
+ if (strstr(reply, "info version -- show the version of QEMU"))
+ return 1;
+ return 0;
+}
static int
qemuMonitorSendDiskPassphrase(qemuMonitorPtr mon,
@@ -3056,6 +3069,13 @@ int qemuMonitorTextBlockJob(qemuMonitorPtr mon,
goto cleanup;
}
+ if (qemuMonitorTextCommandNotFound(reply)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Operation is not supported"));
+ ret = -1;
+ goto cleanup;
+ }
+
ret = qemuMonitorTextParseBlockJob(reply, device, info);
cleanup:
--
1.7.3
13 years, 3 months
[libvirt] [RFC 0/4] Report disk latency information
by Osier Yang
The QEMU side patches are not posted yet, but considering what these
patche series need is only a fixed interface provided by QEMU, posting
it for early reviewing, won't push it before QEMU patches are got pushed
even it got ACK.
Osier
13 years, 3 months
[libvirt] [PATCH] remote: Switch to TLS when connecting to remote socket
by Michal Privoznik
If users wants to connect to remote unix socket, e.g.
'qemu+unix://<remote>/system' currently the <remote> part is ignored,
ending up connecting to localhost. This patch solves this issue by
creating TLS connection.
---
src/remote/remote_driver.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index e5bfa4b..630c8ea 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -325,9 +325,14 @@ doRemoteOpen (virConnectPtr conn,
} else {
if (STRCASEEQ (transport_str, "tls"))
transport = trans_tls;
- else if (STRCASEEQ (transport_str, "unix"))
- transport = trans_unix;
- else if (STRCASEEQ (transport_str, "ssh"))
+ else if (STRCASEEQ (transport_str, "unix")) {
+ /* When connecting to unix socket on remote
+ * machine use TLS to connect to it */
+ if (conn->uri->server)
+ transport = trans_tls;
+ else
+ transport = trans_unix;
+ } else if (STRCASEEQ (transport_str, "ssh"))
transport = trans_ssh;
else if (STRCASEEQ (transport_str, "ext"))
transport = trans_ext;
--
1.7.3.4
13 years, 3 months
[libvirt] [PATCH] [BUGFIX][PATCH] send-key: fix scan keycode map
by KAMEZAWA Hiroyuki
Now, bad key-code in send-key can cause segmentation fault in libvirt.
(example)
% virsh send-key --codeset win32 12
error: End of file while reading data: Input/output error
This is caused by overrun at scanning keycode array.
Fix it.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu(a)jp.fujitsu.com>
---
src/util/virkeycode.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/util/virkeycode.c b/src/util/virkeycode.c
index 4d54060..0d42767 100644
--- a/src/util/virkeycode.c
+++ b/src/util/virkeycode.c
@@ -118,7 +118,7 @@ static int __virKeycodeValueTranslate(unsigned int from_offset,
{
int i;
- for (i = 0; ARRAY_CARDINALITY(virKeycodes); i++) {
+ for (i = 0; i < ARRAY_CARDINALITY(virKeycodes); i++) {
if (getfield(virKeycodes + i, unsigned short, from_offset) == key_value)
return getfield(virKeycodes + i, unsigned short, to_offset);
}
--
1.7.4.1
13 years, 3 months
[libvirt] portability issue on Centos 6.0
by Daniel Veillard
I just tred compiling 0.9.4 and git head on Centos 6.0, for the
possible libvirt.org server replacement and it fails in both cases
with:
CC libvirtd-remote.o
remote.c: In function 'remoteDispatchAuthPolkit':
remote.c:2161: error: invalid initializer
This correspond to the following macro
PROBE(CLIENT_AUTH_ALLOW, "fd=%d, auth=%d, username=%s",
virNetServerClientGetFD(client), REMOTE_AUTH_POLKIT,
ident);
I'm a bit lost how the expansion could lead to this and why, unless the
DTrace support in Centos 6 is slightly different than on RHEL, I will
look but if someone has an idea :-)
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
13 years, 3 months
[libvirt] How to avoid the disk still persistent after no persistent hotplug and with restarting libvirtd then.
by Osier Yang
Libvirt loads the domain conf from the status file
(/var/run/libvirt/qemu/$dom.xml)
if the domain is running, the problem if one restart libvirtd just after
some changing on the domain conf, and then destroy/start the guest.
libvirt will never known what the original domain conf is then.
(vm->newdef is NULL at this moment, generally libvirt restore the domain
conf
to the original conf (vm->newDef) when destroying and shutdown).
Following is a demo of the problem:
1) hotplug a disk to a running domain without "--persistent" specified.
2) restart libvirtd
3) Destroy/start the guest
4) you will see the hotpluged disk is still there.
The solution in my mind is to add some attribute to the status XML, such
as "live_updated=1", and do the checking when loading the domain conf
from status XML:
* if "live_updated=1", then loads the domain conf from the persistent
domain XML.
But the problem is:
For a persistent domain, if one made changes on the domain conf both
persistently and transiently, we have no way to known which part are
changed. Loading from the persistent domain conf is not correct either.
For a transient domain, we still have no way to get the original domain
conf,
that means one will still be surprised when seeing the the disk is still
there.
Any idea on this?
Thanks
Osier
13 years, 3 months
[libvirt] Proposal: A place to store metadata about guests
by Richard W.M. Jones
I think we need a place to store general metadata about guests.
Here are some uses:
- Store data about available installer ISOs, guests which are
archived and not known to libvirt.
- Replace the guest inspection thread in virt-manager. virt-manager
would just collect the data from the store. The inspection data
would be generated by another process.
- Expand on <description/> field in the libvirt XML, and satisfy
various requests we've had for a place to store metadata and extend
libvirt XML.
- Store data on behalf of applications, esp. virt-manager.
I'm not envisaging a database or daemon for this. Just a simple
directory per host containing flat files. Perhaps we can add some
tools or a library to make creation/querying of these files easy. It
would be nice if the database was made available over the network
(Avahi?).
You could also use this database to answer questions like:
- "Do I have a Debian wheezy 32 bit guest anywhere on my network?"
- "Does any guest have libpng <= <vulnerable-version> installed?"
- "Bring up a Fedora 14 instance" (the tools would have to locate a
suitable install ISO and put together the correct virt-install
command line)
There is some crossover with VDSM and even RHEV-M here.
Thoughts?
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
libguestfs lets you edit virtual machines. Supports shell scripting,
bindings from many languages. http://libguestfs.org
13 years, 3 months
[libvirt] [libvirt-snmp][PATCH 1/3] subagent: Avoid dead code
by Michal Privoznik
Detected by Coverity
---
src/libvirtMib_subagent.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/libvirtMib_subagent.c b/src/libvirtMib_subagent.c
index f5749be..ee99fb9 100644
--- a/src/libvirtMib_subagent.c
+++ b/src/libvirtMib_subagent.c
@@ -60,7 +60,7 @@ main (int argc, char **argv) {
/* Defs for arg-handling code: handles setting of policy-related variables */
int ch;
extern char *optarg;
- int dont_fork = 0, use_syslog = 0;
+ int dont_fork = 0, use_syslog = 1;
char *agentx_socket = NULL;
while ((ch = getopt(argc, argv, "D:fHLMx:")) != EOF)
--
1.7.3.4
13 years, 3 months
[libvirt] [PATCH v2] qemu: Allow graceful domain destroy
by Michal Privoznik
This patch introduces support for domain destroying via 'quit' monitor
command which gives qemu time to flush caches and therefore prevent
disks corruption. However, qemu can be unresponsive and to prevent
waiting indefinitely, execute command in a separate thread and wait
reasonable time (QEMU_QUIT_WAIT_SECONDS) on a condition. If we hit
timeout, qemu is qemuProcessKill'ed which causes monitor close and
therefore also thread being terminable.
The synchronization between qemu driver and monitor-quit thread is done
through mutex and condition. However, this alone is not enough. If a
condition is signalized but without anybody listening signal is lost. To
prevent this a boolean variable is used that is set iff nobody is
listening but condition would be signalized, or iff driver is waiting on
given condition.
---
diff to v1:
- more debug printings
- don't test (!flags) but (!(flags & VIR_DOMAIN_DESTROY_FLUSH_CACHE))
include/libvirt/libvirt.h.in | 11 ++-
src/qemu/qemu_driver.c | 146 ++++++++++++++++++++++++++++++++++++++++--
src/qemu/qemu_monitor.c | 13 ++++
src/qemu/qemu_monitor.h | 2 +
src/qemu/qemu_monitor_json.c | 22 ++++++
src/qemu/qemu_monitor_json.h | 1 +
src/qemu/qemu_monitor_text.c | 20 ++++++
src/qemu/qemu_monitor_text.h | 1 +
tools/virsh.c | 9 ++-
9 files changed, 213 insertions(+), 12 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index aa29fb6..0610b53 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -919,10 +919,13 @@ virConnectPtr virDomainGetConnect (virDomainPtr domain);
* Domain creation and destruction
*/
-/*
- * typedef enum {
- * } virDomainDestroyFlagsValues;
- */
+
+typedef enum {
+ VIR_DOMAIN_DESTROY_FLUSH_CACHE = 1 << 0, /* In hypervisors supporting this,
+ try to get cache flushed prior
+ to destroying the domain */
+} virDomainDestroyFlagsValues;
+
virDomainPtr virDomainCreateXML (virConnectPtr conn,
const char *xmlDesc,
unsigned int flags);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c8dda73..44f4bbd 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1564,6 +1564,47 @@ cleanup:
return ret;
}
+struct qemuDomainDestroyHelperData {
+ struct qemud_driver *driver;
+ virDomainObjPtr vm;
+ qemuDomainObjPrivatePtr priv;
+ virMutex lock;
+ virCond cond;
+ bool guard;
+};
+
+static void
+qemuDomainDestroyHelper(void *opaque)
+{
+ struct qemuDomainDestroyHelperData *data = opaque;
+ struct qemud_driver *driver = data->driver;
+ virDomainObjPtr vm = data->vm;
+ qemuDomainObjPrivatePtr priv = data->priv;
+
+ /* Job was already obtained by caller */
+ VIR_DEBUG("Destroy thread started, sending 'quit' command.");
+ qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ qemuMonitorQuit(priv->mon);
+ qemuDomainObjExitMonitorWithDriver(driver, vm);
+ VIR_DEBUG("Command finished.");
+
+ /* To avoid loosing signal, we need to remember
+ * we tried to send one, but nobody was waiting
+ * for it.
+ */
+ virMutexLock(&data->lock);
+ if (data->guard) {
+ VIR_DEBUG("Driver is listening, signalize on condition");
+ virCondSignal(&data->cond);
+ } else {
+ VIR_DEBUG("Nobody's listening, setting guard variable");
+ data->guard = true;
+ }
+ virMutexUnlock(&data->lock);
+ VIR_DEBUG("Destroy thread exiting");
+}
+
+#define QEMU_QUIT_WAIT_SECONDS 5
static int
qemuDomainDestroyFlags(virDomainPtr dom,
@@ -1574,8 +1615,13 @@ qemuDomainDestroyFlags(virDomainPtr dom,
int ret = -1;
virDomainEventPtr event = NULL;
qemuDomainObjPrivatePtr priv;
+ bool use_thread = false;
+ bool use_kill = false;
+ virThread destroy_thread;
+ struct qemuDomainDestroyHelperData data;
+ unsigned long long then;
- virCheckFlags(0, -1);
+ virCheckFlags(VIR_DOMAIN_DESTROY_FLUSH_CACHE, -1);
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -1590,12 +1636,14 @@ qemuDomainDestroyFlags(virDomainPtr dom,
priv = vm->privateData;
priv->fakeReboot = false;
- /* Although qemuProcessStop does this already, there may
- * be an outstanding job active. We want to make sure we
- * can kill the process even if a job is active. Killing
- * it now means the job will be released
- */
- qemuProcessKill(vm);
+ if (!(flags & VIR_DOMAIN_DESTROY_FLUSH_CACHE)) {
+ /* Although qemuProcessStop does this already, there may
+ * be an outstanding job active. We want to make sure we
+ * can kill the process even if a job is active. Killing
+ * it now means the job will be released
+ */
+ qemuProcessKill(vm);
+ }
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_DESTROY) < 0)
goto cleanup;
@@ -1606,6 +1654,78 @@ qemuDomainDestroyFlags(virDomainPtr dom,
goto endjob;
}
+ if (flags & VIR_DOMAIN_DESTROY_FLUSH_CACHE) {
+ /* Try to shutdown domain gracefully.
+ * Send 'quit' to qemu. However, qemu can be unresponsive.
+ * Therefore create a separate thread in which we execute
+ * that monitor comand. Wait max QEMU_QUIT_WAIT_SECONDS.
+ */
+ VIR_DEBUG("Trying to gracefully shutdown %s", vm->def->name);
+ if (virMutexInit(&data.lock) < 0) {
+ virReportOOMError();
+ goto endjob;
+ }
+
+ if (virCondInit(&data.cond) < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot initialize thread condition"));
+ virMutexDestroy(&data.lock);
+ goto endjob;
+ }
+
+ data.driver = driver;
+ data.vm = vm;
+ data.priv = priv;
+ data.guard = false;
+
+ VIR_DEBUG("Spawning thread to run 'quit' command");
+ if (virThreadCreate(&destroy_thread, true,
+ qemuDomainDestroyHelper, &data) < 0) {
+ virReportSystemError(errno, "%s",
+ _("unable to create destroy thread"));
+ ignore_value(virCondDestroy(&data.cond));
+ virMutexDestroy(&data.lock);
+ goto endjob;
+ }
+ use_thread = true;
+
+ if (virTimeMs(&then) < 0)
+ goto endjob;
+
+ then += QEMU_QUIT_WAIT_SECONDS * 1000;
+
+ /* How synchronization with destroy thread works:
+ * Basically wait on data.cond. But because conditions
+ * does not 'remember' that they have been signalized
+ * data.guard is used. Practically, data.guard says
+ * to destroy thread if we are waiting on condition
+ * and to us whether we should even try.
+ */
+ virMutexLock(&data.lock);
+ if (!data.guard) {
+ data.guard = true;
+ VIR_DEBUG("Waiting for thread to exit");
+ if (virCondWaitUntil(&data.cond, &data.lock, then) < 0) {
+ if (errno == ETIMEDOUT) {
+ VIR_DEBUG("Condition timeout");
+ use_kill = true;
+ data.guard = false;
+ } else {
+ virReportSystemError(errno, "%s", _("unable to wait "
+ "on condition"));
+ virMutexUnlock(&data.lock);
+ goto endjob;
+ }
+ }
+ } else {
+ VIR_DEBUG("Guard variable set, thread exited");
+ }
+ virMutexUnlock(&data.lock);
+
+ if (use_kill)
+ qemuProcessKill(vm);
+ }
+
qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_DESTROYED);
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED,
@@ -1626,6 +1746,18 @@ endjob:
vm = NULL;
cleanup:
+ if (use_thread) {
+ VIR_DEBUG("Thread used, clean it up");
+ virMutexLock(&data.lock);
+ if (!data.guard) {
+ data.guard = true;
+ ignore_value(virCondWait(&data.cond, &data.lock));
+ }
+ virMutexUnlock(&data.lock);
+ ignore_value(virCondDestroy(&data.cond));
+ virMutexDestroy(&data.lock);
+ virThreadJoin(&destroy_thread);
+ }
if (vm)
virDomainObjUnlock(vm);
if (event)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index db6107c..41b9c5c 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2475,3 +2475,16 @@ int qemuMonitorBlockJob(qemuMonitorPtr mon,
ret = qemuMonitorTextBlockJob(mon, device, bandwidth, info, mode);
return ret;
}
+
+int qemuMonitorQuit(qemuMonitorPtr mon)
+{
+ int ret;
+
+ VIR_DEBUG("mon=%p", mon);
+
+ if (mon->json)
+ ret = qemuMonitorJSONQuit(mon);
+ else
+ ret = qemuMonitorTextQuit(mon);
+ return ret;
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index f241c9e..3fe6bb9 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -475,6 +475,8 @@ int qemuMonitorBlockJob(qemuMonitorPtr mon,
virDomainBlockJobInfoPtr info,
int mode);
+int qemuMonitorQuit(qemuMonitorPtr mon);
+
/**
* When running two dd process and using <> redirection, we need a
* shell that will not truncate files. These two strings serve that
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 7adfb26..1f078cd 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2956,3 +2956,25 @@ int qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
virJSONValueFree(reply);
return ret;
}
+
+
+int qemuMonitorJSONQuit(qemuMonitorPtr mon)
+{
+ int ret = -1;
+ virJSONValuePtr cmd = NULL;
+ virJSONValuePtr reply = NULL;
+
+ cmd = qemuMonitorJSONMakeCommand("quit", NULL);
+
+ if (!cmd)
+ return -1;
+
+ ret =qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (ret == 0)
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 9512793..2a7df76 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -231,4 +231,5 @@ int qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
virDomainBlockJobInfoPtr info,
int mode);
+int qemuMonitorJSONQuit(qemuMonitorPtr mon);
#endif /* QEMU_MONITOR_JSON_H */
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 52d924a..ca9c21b 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -3063,3 +3063,23 @@ cleanup:
VIR_FREE(reply);
return ret;
}
+
+
+int qemuMonitorTextQuit(qemuMonitorPtr mon)
+{
+ const char *cmd = "quit";
+ char *reply = NULL;
+ int ret = -1;
+
+ if (qemuMonitorHMPCommand(mon, cmd, &reply) < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("cannot run monitor command"));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(reply);
+ return ret;
+}
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index b250738..9ade938 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -224,4 +224,5 @@ int qemuMonitorTextBlockJob(qemuMonitorPtr mon,
virDomainBlockJobInfoPtr info,
int mode);
+int qemuMonitorTextQuit(qemuMonitorPtr mon);
#endif /* QEMU_MONITOR_TEXT_H */
diff --git a/tools/virsh.c b/tools/virsh.c
index 7d849ec..4c7962b 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2567,6 +2567,8 @@ static const vshCmdInfo info_destroy[] = {
static const vshCmdOptDef opts_destroy[] = {
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
+ {"flush", VSH_OT_BOOL, 0, N_("try to flush hypervisor's cache prior to "
+ "destroying the domain")},
{NULL, 0, 0, NULL}
};
@@ -2576,6 +2578,7 @@ cmdDestroy(vshControl *ctl, const vshCmd *cmd)
virDomainPtr dom;
bool ret = true;
const char *name;
+ int flags = 0;
if (!vshConnectionUsability(ctl, ctl->conn))
return false;
@@ -2583,7 +2586,11 @@ cmdDestroy(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
return false;
- if (virDomainDestroy(dom) == 0) {
+ if (vshCommandOptBool(cmd, "flush"))
+ flags |= VIR_DOMAIN_DESTROY_FLUSH_CACHE;
+
+ if ((!flags && virDomainDestroy(dom) == 0) ||
+ virDomainDestroyFlags(dom, flags) == 0) {
vshPrint(ctl, _("Domain %s destroyed\n"), name);
} else {
vshError(ctl, _("Failed to destroy domain %s"), name);
--
1.7.3.4
13 years, 3 months
[libvirt] USB2 controllers & domain XML
by Marc-André Lureau
Hi
I have started looking at: https://bugzilla.redhat.com/show_bug.cgi?id=725670
My initial thought was to just add a new type of controller:
<controller type='usb2' index='0'/>
But it also needs the 3 companion UHCI controllers (see bug). We can
either include them implicitely (not really elegant in libvirt, but
doable), or with more flexibility list all the controllers in the XML:
<controller type='ich9-usb-ehci1' index='0'/>
<controller type='ich9-usb-uhci1' index='0' masterbus='0' firstport='0'>
<controller type='ich9-usb-uhci2' index='0' masterbus='0' firstport='2'>
<controller type='ich9-usb-uhci3' index='0' masterbus='0' firstport='4'>
Any other idea?
Daniel, have you also started working on USB2 & usb-redir support?
regards
--
Marc-André Lureau
13 years, 3 months