[libvirt] "Connection does not support host device enumeration"
by Kaushal Shriyan
Hi,
I have "20:04.0 Network controller: Sangoma Technologies Corp. A104d
QUAD T1/E1 AFT card" on Host OS, Its not visible on guest OS using
linux KVM application.
I did open the window for guest from virt-manager on my Ubuntu Linux
Desktop 11.04, shut down the guest, then select the "Details" view
from the menu on that window, and click "Add Hardware" at the bottom,
select "PCI Host Device" in the selections on the left, and find your
device in the list of host devices on the right. Then click "Finish".
Finally, start your guest up again, and the device should appear.
I get "Connection does not support host device enumeration" Any clue ?
libvirt-0.8.2-22.el5 version running on CentOS Linux Server version 5.6
Please let me know if you need any additional information
Regards,
Kaushal
13 years, 1 month
[libvirt] [RFC PATCH] snapshot: better virsh handling of missing current, parent
by Eric Blake
Previously, virsh 'snapshot-parent' and 'snapshot-current' were
completely silent in the case where the code conclusively proved
there was no parent or current snapshot, but differed in exit
status; this silence caused some confusion on whether the commands
worked. Furthermore, commit d1be48f introduced a regression where
snapshot-parent would leak output about an unknown function, but
only on the first attempt, when talking to an older server that
lacks virDomainSnapshotGetParent. This changes things to consistenly
report an error message and exit with status 1 when no snapshot
exists, and to avoid leaking unknown function warnings when using
fallbacks.
* tools/virsh.c (vshGetSnapshotParent): Alter signature, to
distinguish between real error and missing parent. Don't pollute
last_error on success.
(cmdSnapshotParent): Adjust caller. Always output message on
failure.
(vshGetSnapshotParent): Adjust caller.
(cmdSnapshotCurrent): Always output message on failure.
---
This patch is an RFC because of backwards-compatibility concerns:
Currently, snapshot-current outputs nothing but has status 0 if
there is no current snapshot; but snapshot-parent outputs nothing
but has status 1 if there is no parent snapshot. Either way, we
have an inconsistency that needs to be fixed, and gaining consistency
means breaking backwards compatibility with at least one command.
Approach 1 (this patch): change snapshot-parent and snapshot-current
to always output something, whether to stdout on success or to
stderr on failure, with lack of a snapshot being considered a
failure (where snapshot-current used to treat it as success).
Approach 2 (not written) since snapshot-current existed much longer,
makesnapshot-parent consistent by giving status 0 when it is silent.
Preferences? (I guess mine is approach 1, by evidence of this patch).
tools/virsh.c | 54 +++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 39 insertions(+), 15 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 1909dce..179cda5 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -12945,6 +12945,7 @@ cmdSnapshotCurrent(vshControl *ctl, const vshCmd *cmd)
char *xml = NULL;
const char *snapshotname = NULL;
unsigned int flags = 0;
+ const char *domname;
if (vshCommandOptBool(cmd, "security-info"))
flags |= VIR_DOMAIN_XML_SECURE;
@@ -12952,7 +12953,7 @@ cmdSnapshotCurrent(vshControl *ctl, const vshCmd *cmd)
if (!vshConnectionUsability(ctl, ctl->conn))
goto cleanup;
- dom = vshCommandOptDomain(ctl, cmd, NULL);
+ dom = vshCommandOptDomain(ctl, cmd, &domname);
if (dom == NULL)
goto cleanup;
@@ -12986,9 +12987,12 @@ cmdSnapshotCurrent(vshControl *ctl, const vshCmd *cmd)
}
current = virDomainHasCurrentSnapshot(dom, 0);
- if (current < 0)
+ if (current < 0) {
+ goto cleanup;
+ } else if (!current) {
+ vshError(ctl, _("domain '%s' has no current snapshot"), domname);
goto cleanup;
- else if (current) {
+ } else {
const char *name = NULL;
if (!(snapshot = virDomainSnapshotCurrent(dom, 0)))
@@ -13010,6 +13014,8 @@ cmdSnapshotCurrent(vshControl *ctl, const vshCmd *cmd)
ret = true;
cleanup:
+ if (!ret)
+ virshReportError(ctl);
VIR_FREE(xml);
if (snapshot)
virDomainSnapshotFree(snapshot);
@@ -13020,26 +13026,33 @@ cleanup:
}
/* Helper function to get the name of a snapshot's parent. Caller
- * must free the result. */
-static char *
-vshGetSnapshotParent(vshControl *ctl, virDomainSnapshotPtr snapshot)
+ * must free the result. Returns 0 on success (including when it was
+ * proven no parent exists), and -1 on failure with error reported
+ * (such as no snapshot support or domain deleted in meantime). */
+static int
+vshGetSnapshotParent(vshControl *ctl, virDomainSnapshotPtr snapshot,
+ char **parent_name)
{
virDomainSnapshotPtr parent = NULL;
char *xml = NULL;
xmlDocPtr xmldoc = NULL;
xmlXPathContextPtr ctxt = NULL;
- char *parent_name = NULL;
+ int ret = -1;
+
+ *parent_name = NULL;
/* Try new API, since it is faster. */
if (!ctl->useSnapshotGetXML) {
parent = virDomainSnapshotGetParent(snapshot, 0);
if (parent) {
- /* API works, and virDomainSnapshotGetName will succeed */
- parent_name = vshStrdup(ctl, virDomainSnapshotGetName(parent));
+ /* API works, and virDomainSnapshotGetName will be accurate */
+ *parent_name = vshStrdup(ctl, virDomainSnapshotGetName(parent));
+ ret = 0;
goto cleanup;
}
if (last_error->code == VIR_ERR_NO_DOMAIN_SNAPSHOT) {
/* API works, and we found a root with no parent */
+ ret = 0;
goto cleanup;
}
/* API didn't work, fall back to XML scraping. */
@@ -13054,15 +13067,23 @@ vshGetSnapshotParent(vshControl *ctl, virDomainSnapshotPtr snapshot)
if (!xmldoc)
goto cleanup;
- parent_name = virXPathString("string(/domainsnapshot/parent/name)", ctxt);
+ *parent_name = virXPathString("string(/domainsnapshot/parent/name)", ctxt);
+ ret = 0;
cleanup:
+ if (ret < 0) {
+ virshReportError(ctl);
+ vshError(ctl, "%s", _("unable to determine if snapshot has parent"));
+ } else {
+ virFreeError(last_error);
+ last_error = NULL;
+ }
if (parent)
virDomainSnapshotFree(parent);
xmlXPathFreeContext(ctxt);
xmlFreeDoc(xmldoc);
VIR_FREE(xml);
- return parent_name;
+ return ret;
}
/*
@@ -13187,13 +13208,13 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
if (snapshot)
virDomainSnapshotFree(snapshot);
snapshot = virDomainSnapshotLookupByName(dom, names[i], 0);
- if (!snapshot) {
+ if (!snapshot ||
+ vshGetSnapshotParent(ctl, snapshot, &parents[i]) < 0) {
while (--i >= 0)
VIR_FREE(parents[i]);
VIR_FREE(parents);
goto cleanup;
}
- parents[i] = vshGetSnapshotParent(ctl, snapshot);
}
for (i = 0 ; i < actual ; i++) {
memset(indentBuf, '\0', sizeof indentBuf);
@@ -13389,9 +13410,12 @@ cmdSnapshotParent(vshControl *ctl, const vshCmd *cmd)
if (snapshot == NULL)
goto cleanup;
- parent = vshGetSnapshotParent(ctl, snapshot);
- if (!parent)
+ if (vshGetSnapshotParent(ctl, snapshot, &parent) < 0)
goto cleanup;
+ if (!parent) {
+ vshError(ctl, _("snapshot '%s' has no parent"), name);
+ goto cleanup;
+ }
vshPrint(ctl, "%s", parent);
--
1.7.4.4
13 years, 1 month
[libvirt] Deadlock when using custom handlers
by Guido Günther
Hi,
virt-viewer is using it's own virEventRegisterImpl. With current libvirt
this can deadlock when connection to nonexistant URIs like
qemu+ssh:///unknownhost.example.com/system
like:
23:47:00.338: 1526: debug : doRemoteOpen:503 : proceeding with name = qemu:///system
23:47:00.338: 1526: debug : doRemoteOpen:513 : Connecting with transport 2
23:47:00.338: 1526: debug : virCommandRunAsync:2042 : About to run LC_ALL=C LD_LIBRARY_PATH=/var/scratch/debian/libvirt/upstream/libvirt/src/.libs/ PATH=/usr/local/bin:/usr/bin:/bin:/usr/games:/home/agx/bin:/sbin:/usr/sbin:/usr/lib/git-core HOME=/home/agx USER=agx LOGNAME=agx SSH_AUTH_SOCK=/tmp/keyring-RNvlnT/ssh DISPLAY=:0 ssh pustekiste nc -U /var/run/libvirt/libvirt-sock-ro
23:47:00.339: 1526: debug : virCommandRunAsync:2058 : Command result 0, with PID 1527
23:47:00.339: 1526: debug : virNetSocketNew:115 : localAddr=(nil) remoteAddr=(nil) fd=6 errfd=8 pid=1527
23:47:00.339: 1526: debug : virNetSocketNew:173 : sock=0x8926d20 localAddrStr=(null) remoteAddrStr=(null)
** (virt-viewer:1526): DEBUG: Add handle 6 1 0x8926d20
23:47:00.339: 1526: debug : virNetClientNew:160 : client=0xb5b5f008 refs=2
23:47:00.339: 1526: debug : doRemoteOpen:640 : Trying authentication
23:47:00.339: 1526: debug : virNetMessageNew:44 : msg=0xb5b1e008
23:47:00.340: 1526: debug : virNetMessageEncodePayload:255 : Encode length as 28
23:47:00.340: 1526: debug : virNetClientIO:1035 : program=536903814 version=1 serial=0 proc=66 type=0 length=28 dispatch=(nil)
23:47:00.340: 1526: debug : virNetClientIO:1103 : We have the buck 0x8939940 0x8939940
23:47:00.350: 1526: debug : virNetClientIOEventLoop:979 : Giving up the buck due to I/O error 0x8939940 (nil)
23:47:00.350: 1526: debug : virNetClientIO:1130 : All done with our call (nil) 0x8939940 -1
23:47:00.350: 1526: debug : virNetMessageFree:57 : msg=0xb5b1e008
** (virt-viewer:1526): DEBUG: Remove handle 1 6
<deadlock>
Gdb displays the deadlock nicely:
#0 0xb7710424 in __kernel_vsyscall ()
#1 0xb692cf02 in __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/lowlevellock.S:142
#2 0xb692839b in _L_lock_728 () from /lib/i386-linux-gnu/i686/cmov/libpthread.so.0
#3 0xb69281c1 in __pthread_mutex_lock (mutex=0x95e1c30) at pthread_mutex_lock.c:61
#4 0xb698fd07 in virMutexLock (m=0x95e1c30) at util/threads-pthread.c:85
#5 0xb6a5dd56 in virNetSocketEventFree (opaque=0x95e1c30) at rpc/virnetsocket.c:1147
#6 0x080514a1 in virt_viewer_events_remove_handle (watch=1) at virt-viewer-events.c:178
#7 0xb697264e in virEventRemoveHandle (watch=1) at util/event.c:84
#8 0xb6a608ed in virNetSocketRemoveIOCallback (sock=0x95e1c30) at rpc/virnetsocket.c:1221
#9 0xb6a57114 in virNetClientClose (client=0xb5b7e008) at rpc/virnetclient.c:280
#10 0xb6a46fc4 in doRemoteOpen (conn=0x95e1aa8, priv=0x95b1370, auth=0xbfc3b178, flags=1) at remote/remote_driver.c:705
#11 0xb6a49612 in remoteOpen (conn=0x95e1aa8, auth=0xbfc3b178, flags=1) at remote/remote_driver.c:820
#12 0xb69f70c6 in do_open (name=0x95aac10 "qemu+ssh://pustekiste:2222/system", auth=0xbfc3b178, flags=1) at libvirt.c:1054
#13 0xb69f9b88 in virConnectOpenAuth (name=0x95aac10 "qemu+ssh://pustekiste:2222/system", auth=0xbfc3b178, flags=1) at libvirt.c:1280
#14 0x080500cf in virt_viewer_start (app=0x95a1010) at virt-viewer.c:483
#15 0x08053be8 in virt_viewer_app_start (self=0x95a1010) at virt-viewer-app.c:1044
#16 0x0804f54d in main (argc=1, argv=0xbfc3b3f4) at virt-viewer-main.c:120
which is the sock->lock:
virNetSocketRemoveIOCallback holds sock->lock
-> virEventRemoveHandle
-> impl_remove_handle
-> opaque->ff
-> virNetSocketEventFree want to hold sock->lock
Working around this by removing the locks from
virNetSocketRemoveIOCallback leads to another deadlock:
#0 0xb77de424 in __kernel_vsyscall ()
#1 0xb69faf02 in __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/lowlevellock.S:142
#2 0xb69f639b in _L_lock_728 () from /lib/i386-linux-gnu/i686/cmov/libpthread.so.0
#3 0xb69f61c1 in __pthread_mutex_lock (mutex=0xb5c4c00c) at pthread_mutex_lock.c:61
#4 0xb6a5dd07 in virMutexLock (m=0xb5c4c00c) at util/threads-pthread.c:85
#5 0xb6b24a98 in virNetClientLock (client=0xb5c4c008) at rpc/virnetclient.c:99
#6 virNetClientFree (client=0xb5c4c008) at rpc/virnetclient.c:243
#7 0xb6b250b7 in virNetClientEventFree (opaque=0xb5c4c008) at rpc/virnetclient.c:117
#8 0xb6b2bd82 in virNetSocketEventFree (opaque=0x8aabc30) at rpc/virnetsocket.c:1156
#9 0x080514a1 in virt_viewer_events_remove_handle (watch=1) at virt-viewer-events.c:178
#10 0xb6a4064e in virEventRemoveHandle (watch=1) at util/event.c:84
#11 0xb6b2e8e5 in virNetSocketRemoveIOCallback (sock=0x8aabc30) at rpc/virnetsocket.c:1219
#12 0xb6b25114 in virNetClientClose (client=0xb5c4c008) at rpc/virnetclient.c:280
#13 0xb6b14fc4 in doRemoteOpen (conn=0x8aabaa8, priv=0x8a7b370, auth=0xbfbf1798, flags=1) at remote/remote_driver.c:705
#14 0xb6b17612 in remoteOpen (conn=0x8aabaa8, auth=0xbfbf1798, flags=1) at remote/remote_driver.c:820
#15 0xb6ac50c6 in do_open (name=0x8a74c10 "qemu+ssh://pustekiste:2222/system", auth=0xbfbf1798, flags=1) at libvirt.c:1054
#16 0xb6ac7b88 in virConnectOpenAuth (name=0x8a74c10 "qemu+ssh://pustekiste:2222/system", auth=0xbfbf1798, flags=1) at libvirt.c:1280
#17 0x080500cf in virt_viewer_start (app=0x8a6b010) at virt-viewer.c:483
#18 0x08053be8 in virt_viewer_app_start (self=0x8a6b010) at virt-viewer-app.c:1044
#19 0x0804f54d in main (argc=1, argv=0xbfbf1a14) at virt-viewer-main.c:120
which is the virNetClient lock:
virNetClientClose holds client->lock
-> virNetSocketRemoveIOCallback
-> virEventRemoveHandle
-> impl_remove_handle
-> virNetSocketEventFree
-> virNetClientEventFree wants the lock
I didn't see a simple way to fix this but would welcome any suggestions.
Cheers,
-- Guido
13 years, 1 month
[libvirt] [RFC PATCH] lxc: don't return error on GetInfo when cgroups not yet set up
by Serge E. Hallyn
Nova (openstack) calls libvirt to create a container, then
periodically checks using GetInfo to see whether the container
is up. If it does this too quickly, then libvirt returns an
error, which in libvirt.py causes an exception to be raised,
the same type as if the container was bad.
This may not be the best way to handle it, but with this
patch, we assume that a -ENOENT return from virCgroupForDomain
means the cgroups are not yet set up, and so we return the
same values for cpu and memory usage as if the domain was not
active.
Signed-off-by: Serge Hallyn <serge.hallyn(a)canonical.com>
---
src/lxc/lxc_driver.c | 37 +++++++++++++++++++++----------------
1 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 4b62600..a68b8e7 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -542,26 +542,31 @@ static int lxcDomainGetInfo(virDomainPtr dom,
info->cpuTime = 0;
info->memory = vm->def->mem.cur_balloon;
} else {
- if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
+ int ret = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0);
+ if (ret == -ENOENT) {
+ /* cgroups are not set up yet */
+ info->cpuTime = 0;
+ info->memory = vm->def->mem.cur_balloon;
+ } else if (ret != 0) {
lxcError(VIR_ERR_INTERNAL_ERROR,
_("Unable to get cgroup for %s"), vm->def->name);
goto cleanup;
- }
-
- if (virCgroupGetCpuacctUsage(cgroup, &(info->cpuTime)) < 0) {
- lxcError(VIR_ERR_OPERATION_FAILED,
- "%s", _("Cannot read cputime for domain"));
- goto cleanup;
- }
- if ((rc = virCgroupGetMemoryUsage(cgroup, &(info->memory))) < 0) {
- lxcError(VIR_ERR_OPERATION_FAILED,
- "%s", _("Cannot read memory usage for domain"));
- if (rc == -ENOENT) {
- /* Don't fail if we can't read memory usage due to a lack of
- * kernel support */
- info->memory = 0;
- } else
+ } else {
+ if (virCgroupGetCpuacctUsage(cgroup, &(info->cpuTime)) < 0) {
+ lxcError(VIR_ERR_OPERATION_FAILED,
+ "%s", _("Cannot read cputime for domain"));
goto cleanup;
+ }
+ if ((rc = virCgroupGetMemoryUsage(cgroup, &(info->memory))) < 0) {
+ lxcError(VIR_ERR_OPERATION_FAILED,
+ "%s", _("Cannot read memory usage for domain"));
+ if (rc == -ENOENT) {
+ /* Don't fail if we can't read memory usage due to a lack of
+ * kernel support */
+ info->memory = 0;
+ } else
+ goto cleanup;
+ }
}
}
--
1.7.5.4
13 years, 1 month
[libvirt] [PATCH 1/2] snapshot: implement getparent for esx
by Eric Blake
Pretty easy to paste together compared to existing functions.
* src/esx/esx_driver.c (esxDomainSnapshotGetParent): New function.
---
I can only compile-test this; I'm relying on someone with an actual
esx setup to actually test it. Also, I didn't see anything in
existing code that would efficiently implement
virDomainSnapshotNumChildren; there may an API that I'm not aware of,
but someone else will have to implement that API (Matthias?)
src/esx/esx_driver.c | 41 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index c15c0d6..ab93efd 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -4484,6 +4484,46 @@ esxDomainHasCurrentSnapshot(virDomainPtr domain, unsigned int flags)
static virDomainSnapshotPtr
+esxDomainSnapshotGetParent(virDomainSnapshotPtr snapshot, unsigned int flags)
+{
+ esxPrivate *priv = snapshot->domain->conn->privateData;
+ esxVI_VirtualMachineSnapshotTree *rootSnapshotList = NULL;
+ esxVI_VirtualMachineSnapshotTree *snapshotTree = NULL;
+ esxVI_VirtualMachineSnapshotTree *snapshotTreeParent = NULL;
+ virDomainSnapshotPtr parent = NULL;
+
+ virCheckFlags(0, NULL);
+
+ if (esxVI_EnsureSession(priv->primary) < 0) {
+ return NULL;
+ }
+
+ if (esxVI_LookupRootSnapshotTreeList(priv->primary, snapshot->domain->uuid,
+ &rootSnapshotList) < 0 ||
+ esxVI_GetSnapshotTreeByName(rootSnapshotList, snapshot->name,
+ &snapshotTree, &snapshotTreeParent,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto cleanup;
+ }
+
+ if (!snapshotTreeParent) {
+ ESX_ERROR(VIR_ERR_NO_DOMAIN_SNAPSHOT,
+ _("snapshot '%s' does not have a parent"),
+ snapshotTree->name);
+ goto cleanup;
+ }
+
+ parent = virGetDomainSnapshot(snapshot->domain, snapshotTreeParent->name);
+
+cleanup:
+ esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotList);
+
+ return parent;
+}
+
+
+
+static virDomainSnapshotPtr
esxDomainSnapshotCurrent(virDomainPtr domain, unsigned int flags)
{
esxPrivate *priv = domain->conn->privateData;
@@ -4831,6 +4871,7 @@ static virDriver esxDriver = {
.domainSnapshotListNames = esxDomainSnapshotListNames, /* 0.8.0 */
.domainSnapshotLookupByName = esxDomainSnapshotLookupByName, /* 0.8.0 */
.domainHasCurrentSnapshot = esxDomainHasCurrentSnapshot, /* 0.8.0 */
+ .domainSnapshotGetParent = esxDomainSnapshotGetParent, /* 0.9.7 */
.domainSnapshotCurrent = esxDomainSnapshotCurrent, /* 0.8.0 */
.domainRevertToSnapshot = esxDomainRevertToSnapshot, /* 0.8.0 */
.domainSnapshotDelete = esxDomainSnapshotDelete, /* 0.8.0 */
--
1.7.4.4
13 years, 1 month
[libvirt] [libvirt-glib] gir: fix introspection of asyncs and array delegate
by Marc-André Lureau
---
libvirt-gobject/libvirt-gobject-connection.c | 24 ++++++++++++------------
libvirt-gobject/libvirt-gobject-connection.h | 6 +++---
libvirt-gobject/libvirt-gobject-storage-pool.c | 8 ++++----
libvirt-gobject/libvirt-gobject-storage-pool.h | 2 +-
libvirt-gobject/libvirt-gobject-stream.h | 2 +-
5 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-connection.c b/libvirt-gobject/libvirt-gobject-connection.c
index 90d1566..5fc0a9e 100644
--- a/libvirt-gobject/libvirt-gobject-connection.c
+++ b/libvirt-gobject/libvirt-gobject-connection.c
@@ -431,19 +431,19 @@ gvir_connection_open_helper(GSimpleAsyncResult *res,
* gvir_connection_open_async:
* @conn: the connection
* @cancellable: (allow-none)(transfer none): cancellation object
- * @callback: (transfer none): completion callback
- * @opaque: (transfer none)(allow-none): opaque data for callback
+ * @callback: (scope async): completion callback
+ * @user_data: (closure): opaque data for callback
*/
void gvir_connection_open_async(GVirConnection *conn,
GCancellable *cancellable,
GAsyncReadyCallback callback,
- gpointer opaque)
+ gpointer user_data)
{
GSimpleAsyncResult *res;
res = g_simple_async_result_new(G_OBJECT(conn),
callback,
- opaque,
+ user_data,
gvir_connection_open);
g_simple_async_result_run_in_thread(res,
gvir_connection_open_helper,
@@ -828,19 +828,19 @@ gvir_connection_fetch_domains_helper(GSimpleAsyncResult *res,
* gvir_connection_fetch_domains_async:
* @conn: the connection
* @cancellable: (allow-none)(transfer none): cancellation object
- * @callback: (transfer none): completion callback
- * @opaque: (transfer none)(allow-none): opaque data for callback
+ * @callback: (scope async): completion callback
+ * @user_data: (closure): opaque data for callback
*/
void gvir_connection_fetch_domains_async(GVirConnection *conn,
GCancellable *cancellable,
GAsyncReadyCallback callback,
- gpointer opaque)
+ gpointer user_data)
{
GSimpleAsyncResult *res;
res = g_simple_async_result_new(G_OBJECT(conn),
callback,
- opaque,
+ user_data,
gvir_connection_fetch_domains);
g_simple_async_result_run_in_thread(res,
gvir_connection_fetch_domains_helper,
@@ -889,19 +889,19 @@ gvir_connection_fetch_pools_helper(GSimpleAsyncResult *res,
* gvir_connection_fetch_storage_pools_async:
* @conn: the connection
* @cancellable: (allow-none)(transfer none): cancellation object
- * @callback: (transfer none): completion callback
- * @opaque: (transfer none)(allow-none): opaque data for callback
+ * @callback: (scope async): completion callback
+ * @user_data: (closure): opaque data for callback
*/
void gvir_connection_fetch_storage_pools_async(GVirConnection *conn,
GCancellable *cancellable,
GAsyncReadyCallback callback,
- gpointer opaque)
+ gpointer user_data)
{
GSimpleAsyncResult *res;
res = g_simple_async_result_new(G_OBJECT(conn),
callback,
- opaque,
+ user_data,
gvir_connection_fetch_storage_pools);
g_simple_async_result_run_in_thread(res,
gvir_connection_fetch_pools_helper,
diff --git a/libvirt-gobject/libvirt-gobject-connection.h b/libvirt-gobject/libvirt-gobject-connection.h
index d05f792..2eb58ec 100644
--- a/libvirt-gobject/libvirt-gobject-connection.h
+++ b/libvirt-gobject/libvirt-gobject-connection.h
@@ -77,7 +77,7 @@ gboolean gvir_connection_open(GVirConnection *conn,
void gvir_connection_open_async(GVirConnection *conn,
GCancellable *cancellable,
GAsyncReadyCallback callback,
- gpointer opaque);
+ gpointer user_data);
gboolean gvir_connection_open_finish(GVirConnection *conn,
GAsyncResult *result,
GError **err);
@@ -90,7 +90,7 @@ gboolean gvir_connection_fetch_domains(GVirConnection *conn,
void gvir_connection_fetch_domains_async(GVirConnection *conn,
GCancellable *cancellable,
GAsyncReadyCallback callback,
- gpointer opaque);
+ gpointer user_data);
gboolean gvir_connection_fetch_domains_finish(GVirConnection *conn,
GAsyncResult *result,
GError **err);
@@ -149,7 +149,7 @@ gboolean gvir_connection_fetch_storage_pools(GVirConnection *conn,
void gvir_connection_fetch_storage_pools_async(GVirConnection *conn,
GCancellable *cancellable,
GAsyncReadyCallback callback,
- gpointer opaque);
+ gpointer user_data);
gboolean gvir_connection_fetch_storage_pools_finish(GVirConnection *conn,
GAsyncResult *result,
GError **err);
diff --git a/libvirt-gobject/libvirt-gobject-storage-pool.c b/libvirt-gobject/libvirt-gobject-storage-pool.c
index 8f581eb..fc9cba9 100644
--- a/libvirt-gobject/libvirt-gobject-storage-pool.c
+++ b/libvirt-gobject/libvirt-gobject-storage-pool.c
@@ -385,19 +385,19 @@ gvir_storage_pool_refresh_helper(GSimpleAsyncResult *res,
* gvir_storage_pool_refresh_async:
* @pool: the storage pool
* @cancellable: (allow-none)(transfer none): cancellation object
- * @callback: (transfer none): completion callback
- * @opaque: (transfer none)(allow-none): opaque data for callback
+ * @callback: (scope async): completion callback
+ * @user_data: (closure): opaque data for callback
*/
void gvir_storage_pool_refresh_async(GVirStoragePool *pool,
GCancellable *cancellable,
GAsyncReadyCallback callback,
- gpointer opaque)
+ gpointer user_data)
{
GSimpleAsyncResult *res;
res = g_simple_async_result_new(G_OBJECT(pool),
callback,
- opaque,
+ user_data,
gvir_storage_pool_refresh);
g_simple_async_result_run_in_thread(res,
gvir_storage_pool_refresh_helper,
diff --git a/libvirt-gobject/libvirt-gobject-storage-pool.h b/libvirt-gobject/libvirt-gobject-storage-pool.h
index a789a6a..620f888 100644
--- a/libvirt-gobject/libvirt-gobject-storage-pool.h
+++ b/libvirt-gobject/libvirt-gobject-storage-pool.h
@@ -75,7 +75,7 @@ gboolean gvir_storage_pool_refresh(GVirStoragePool *pool,
void gvir_storage_pool_refresh_async(GVirStoragePool *pool,
GCancellable *cancellable,
GAsyncReadyCallback callback,
- gpointer opaque);
+ gpointer user_data);
gboolean gvir_storage_pool_refresh_finish(GVirStoragePool *pool,
GAsyncResult *result,
GError **err);
diff --git a/libvirt-gobject/libvirt-gobject-stream.h b/libvirt-gobject/libvirt-gobject-stream.h
index fd9c9bb..5181e24 100644
--- a/libvirt-gobject/libvirt-gobject-stream.h
+++ b/libvirt-gobject/libvirt-gobject-stream.h
@@ -62,7 +62,7 @@ struct _GVirStreamClass
/**
* GVirStreamSinkFunc:
* @stream: a #GVirStream
- * @buf: data pointer
+ * @buf: (out) (array length=nbytes) (transfer none): data pointer
* @nbytes: data size
* @user_data: user data passed to the function
* Returns: the number of bytes filled, 0 upon end
--
1.7.6.2
13 years, 1 month
[libvirt] [libvirt-glib] RFC: delay event handle freeing to avoid dead lock
by Marc-André Lureau
Can be reproduced with the updated test.
---
examples/conn-test.c | 20 +++++++++++++++-----
libvirt-glib/libvirt-glib-event.c | 17 +++++++++++++----
2 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/examples/conn-test.c b/examples/conn-test.c
index 08045a4..8ea5ad7 100644
--- a/examples/conn-test.c
+++ b/examples/conn-test.c
@@ -31,12 +31,19 @@ do_connection_open(GObject *source,
{
GVirConnection *conn = GVIR_CONNECTION(source);
GError *err = NULL;
- GMainLoop *loop = opaque;
if (!gvir_connection_open_finish(conn, res, &err)) {
g_error("%s", err->message);
}
g_print("Connected to libvirt\n");
+ g_object_unref(conn);
+}
+
+static void quit(gpointer data,
+ GObject *where_the_object_was)
+{
+ GMainLoop *loop = data;
+
g_main_loop_quit(loop);
}
@@ -47,19 +54,22 @@ int main(int argc, char **argv)
gvir_init_object(&argc, &argv);
- if (argc != 2)
+ if (argc != 2) {
g_error("syntax: %s URI", argv[0]);
-
- conn = gvir_connection_new(argv[1]);
+ return 1;
+ }
loop = g_main_loop_new(g_main_context_default(),
TRUE);
- gvir_connection_open_async(conn, NULL, do_connection_open, loop);
+ conn = gvir_connection_new(argv[1]);
+ g_object_weak_ref(G_OBJECT(conn), quit, loop);
+
gvir_connection_open_async(conn, NULL, do_connection_open, loop);
g_main_loop_run(loop);
+
return 0;
}
diff --git a/libvirt-glib/libvirt-glib-event.c b/libvirt-glib/libvirt-glib-event.c
index a785c93..8b1bddf 100644
--- a/libvirt-glib/libvirt-glib-event.c
+++ b/libvirt-glib/libvirt-glib-event.c
@@ -195,6 +195,18 @@ cleanup:
g_mutex_unlock(eventlock);
}
+static gboolean
+_handle_remove(gpointer data)
+{
+ struct gvir_event_handle *h = data;
+
+ if (h->ff)
+ (h->ff)(h->opaque);
+ free(h);
+
+ return FALSE;
+}
+
static int
gvir_event_handle_remove(int watch)
{
@@ -217,10 +229,7 @@ gvir_event_handle_remove(int watch)
g_source_remove(data->source);
data->source = 0;
data->events = 0;
- if (data->ff)
- (data->ff)(data->opaque);
- free(data);
-
+ g_idle_add(_handle_remove, data);
ret = 0;
cleanup:
--
1.7.6.2
13 years, 1 month
[libvirt] [PATCH 0/2] qemu: make PCI multifunction support more manual
by Laine Stump
Problems have been encountered/realized with the practice of
unconditionally setting the multifunction bit for all functions of all
devices. PATCH 2/2 remedies that (details in its own commit
comment). PATCH 1/2 is a one-liner I fixed in the meantime which will
cause a simple conflict if it's not applied to other branches at the
same time as PATCH 2/2, so I'm sending them together.
13 years, 1 month
[libvirt] [PATCH 0/4] snapshot: listing children
by Eric Blake
My previous API added parent traversal; this one adds child traversal.
virsh snapshot-list domain snapshot --tree
is a nice end result for limiting the output to a particular subset
of the overall hierarchy.
Again, same story about not wiring up ESX and VBox support yet, but
I'll play with that next.
Eric Blake (4):
snapshot: new virDomainSnapshotListChildrenNames API
snapshot: virsh snapshot-list and children
snapshot: remote protocol for snapshot children
snapshot: implement snapshot children listing in qemu
include/libvirt/libvirt.h.in | 27 +++++++--
python/generator.py | 4 ++
python/libvirt-override-api.xml | 12 +++-
python/libvirt-override.c | 45 ++++++++++++++++
src/conf/domain_conf.c | 51 ++++++++++++++++++
src/conf/domain_conf.h | 7 +++
src/driver.h | 12 ++++
src/libvirt.c | 111 +++++++++++++++++++++++++++++++++++++++
src/libvirt_private.syms | 2 +
src/libvirt_public.syms | 2 +
src/qemu/qemu_driver.c | 87 ++++++++++++++++++++++++++++++
src/remote/remote_driver.c | 2 +
src/remote/remote_protocol.x | 25 ++++++++-
src/remote_protocol-structs | 20 +++++++
tools/virsh.c | 64 +++++++++++++++++++---
tools/virsh.pod | 9 +++-
16 files changed, 459 insertions(+), 21 deletions(-)
--
1.7.4.4
13 years, 1 month
[libvirt] [PATCH 1/1] [RFC] lvm storage backend: handle command_names=1 in lvm.conf
by Serge E. Hallyn
If the regexes supported (?:pvs)?, then we could handle this by
optionally matching but not returning the initial command name. But it
doesn't. So add a new char* argument to
virStorageBackendRunProgRegex(). If that argument is NULL then we act
as usual. Otherwise, if the string at that argument is found at the
start of a returned line, we drop that before running the regex.
With this patch, virt-manager shows me lvs with command_names 1 or 0.
The definitions of PVS_BASE etc may want to be moved into the configure
scripts (though given how PVS is found, IIUC that could only happen if
pvs was a link to pvs_real), but in any case no sense dealing with that
until we're sure this is an ok way to handle it.
Signed-off-by: Serge Hallyn <serge.hallyn(a)canonical.com>
---
src/storage/storage_backend.c | 14 ++++++++++----
src/storage/storage_backend.h | 2 +-
src/storage/storage_backend_fs.c | 2 +-
src/storage/storage_backend_iscsi.c | 4 ++--
src/storage/storage_backend_logical.c | 9 ++++++---
5 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index d125504..7a352da 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -1400,7 +1400,7 @@ virStorageBackendRunProgRegex(virStoragePoolObjPtr pool,
const char **regex,
int *nvars,
virStorageBackendListVolRegexFunc func,
- void *data)
+ void *data, char *cmd_to_ignore)
{
int fd = -1, err, ret = -1;
FILE *list = NULL;
@@ -1460,13 +1460,19 @@ virStorageBackendRunProgRegex(virStoragePoolObjPtr pool,
}
while (fgets(line, sizeof(line), list) != NULL) {
+ char *p;
/* Strip trailing newline */
int len = strlen(line);
if (len && line[len-1] == '\n')
line[len-1] = '\0';
+ p = line;
+ /* if cmd_to_ignore is specified, then ignore it */
+ if (strncmp(line, cmd_to_ignore, strlen(cmd_to_ignore)) == 0)
+ p += strlen(cmd_to_ignore);
+
for (i = 0 ; i <= maxReg && i < nregex ; i++) {
- if (regexec(®[i], line, nvars[i]+1, vars, 0) == 0) {
+ if (regexec(®[i], p, nvars[i]+1, vars, 0) == 0) {
maxReg++;
if (i == 0)
@@ -1475,9 +1481,9 @@ virStorageBackendRunProgRegex(virStoragePoolObjPtr pool,
/* NULL terminate each captured group in the line */
for (j = 0 ; j < nvars[i] ; j++) {
/* NB vars[0] is the full pattern, so we offset j by 1 */
- line[vars[j+1].rm_eo] = '\0';
+ p[vars[j+1].rm_eo] = '\0';
if ((groups[ngroup++] =
- strdup(line + vars[j+1].rm_so)) == NULL) {
+ strdup(p + vars[j+1].rm_so)) == NULL) {
virReportOOMError();
goto cleanup;
}
diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
index 67ac32c..aa467f5 100644
--- a/src/storage/storage_backend.h
+++ b/src/storage/storage_backend.h
@@ -140,7 +140,7 @@ int virStorageBackendRunProgRegex(virStoragePoolObjPtr pool,
const char **regex,
int *nvars,
virStorageBackendListVolRegexFunc func,
- void *data);
+ void *data, char *cmd_to_ignore);
int virStorageBackendRunProgNul(virStoragePoolObjPtr pool,
const char **prog,
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 02c4c17..a98db4b 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -266,7 +266,7 @@ virStorageBackendFileSystemNetFindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSE
if (virStorageBackendRunProgRegex(NULL, prog, 1, regexes, vars,
virStorageBackendFileSystemNetFindPoolSourcesFunc,
- &state) < 0)
+ &state, NULL) < 0)
goto cleanup;
retval = virStoragePoolSourceListFormat(&state.list);
diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c
index 346e698..99e69c9 100644
--- a/src/storage/storage_backend_iscsi.c
+++ b/src/storage/storage_backend_iscsi.c
@@ -160,7 +160,7 @@ virStorageBackendISCSISession(virStoragePoolObjPtr pool,
regexes,
vars,
virStorageBackendISCSIExtractSession,
- &session) < 0)
+ &session, NULL) < 0)
return NULL;
if (session == NULL &&
@@ -517,7 +517,7 @@ virStorageBackendISCSIScanTargets(const char *portal,
regexes,
vars,
virStorageBackendISCSIGetTargets,
- &list) < 0) {
+ &list, NULL) < 0) {
return -1;
}
diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c
index 4f42047..7fac7b1 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -205,13 +205,14 @@ virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool,
pool->def->source.name, NULL
};
+#define LVS_BASE "lvs"
if (virStorageBackendRunProgRegex(pool,
prog,
1,
regexes,
vars,
virStorageBackendLogicalMakeVol,
- vol) < 0) {
+ vol, LVS_BASE) < 0) {
return -1;
}
@@ -327,9 +328,10 @@ virStorageBackendLogicalFindPoolSources(virConnectPtr conn ATTRIBUTE_UNUSED,
memset(&sourceList, 0, sizeof(sourceList));
sourceList.type = VIR_STORAGE_POOL_LOGICAL;
+#define PVS_BASE "pvs"
if (virStorageBackendRunProgRegex(NULL, prog, 1, regexes, vars,
virStorageBackendLogicalFindPoolSourcesFunc,
- &sourceList) < 0)
+ &sourceList, PVS_BASE) < 0)
return NULL;
retval = virStoragePoolSourceListFormat(&sourceList);
@@ -496,6 +498,7 @@ virStorageBackendLogicalRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
return -1;
}
+#define VGS_BASE "vgs"
/* Now get basic volgrp metadata */
if (virStorageBackendRunProgRegex(pool,
prog,
@@ -503,7 +506,7 @@ virStorageBackendLogicalRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
regexes,
vars,
virStorageBackendLogicalRefreshPoolFunc,
- NULL) < 0) {
+ NULL, VGS_BASE) < 0) {
virStoragePoolObjClearVols(pool);
return -1;
}
--
1.7.5.4
13 years, 1 month