[Libvir] FYI: bug in remote code

Daniel P. Berrange berrange at redhat.com
Tue Oct 16 20:16:55 UTC 2007


On Tue, Oct 16, 2007 at 08:32:54PM +0100, Daniel P. Berrange wrote:
> On Tue, Oct 16, 2007 at 03:29:26PM -0400, Mark Johnson wrote:
> > >
> > > That means if you don't specify a server / transport, it'll try to use
> > > the local libvirtd daemon. ie, it supports  qemu:///system  URIs
> > > So this is the correct thing to be doing, but the open question is why
> > > it would hang. If libvirtd isn't running locally it should give you
> > > back an immediate rejection / failure, not hang in read.
> > 
> > libvirtd is running locally..  This is libvirtd opening the socket
> > a second time and trying to talk to itself.
> 
> Oh of course. The Xen driver only provides the core VM apis. The networking
> APIs are provided by the QEMU driver impl & re-used by the Xen driver. This
> means that the QEMU driver is called indirectly whenever using the Xen driver.
> So if you want any of the networking APIs to work, you need to have the QEMU
> driver enabled. That said, it should still not call itself recursively when
> the QEMU driver is disabled, so I'll try & figure that out. The long term
> solution is probably to properly separate the QEMU vm vs network driver so
> we can have the latter without the former.

Try this patch.... Basically when running inside the libvirt daemon  there
is an extra set of drivers that are invoked for 'stateful' startup. This
patch implements this driver API for the remote driver setting a global
flag to disable itself. This ensures the remote driver is only activated
when used outside the daemon


Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
-------------- next part --------------
diff -r e5ca9435b159 src/remote_internal.c
--- a/src/remote_internal.c	Tue Oct 16 15:55:17 2007 -0400
+++ b/src/remote_internal.c	Tue Oct 16 16:10:57 2007 -0400
@@ -59,6 +59,8 @@
 #define MAGIC 999               /* private_data->magic if OK */
 #define DEAD 998                /* private_data->magic if dead/closed */
 
+static int inside_daemon = 0;
+
 struct private_data {
     int magic;                  /* Should be MAGIC or DEAD. */
     int sock;                   /* Socket. */
@@ -119,6 +121,16 @@ static void query_free (struct query_fie
 /* GnuTLS functions used by remoteOpen. */
 static int initialise_gnutls (virConnectPtr conn);
 static gnutls_session_t negotiate_gnutls_on_connection (virConnectPtr conn, int sock, int no_verify, const char *hostname);
+
+static int
+remoteStartup(void)
+{
+    /* Mark that we're inside the daemon so we can avoid
+     * re-entering ourselves
+     */
+    inside_daemon = 1;
+    return 0;
+}
 
 /**
  * remoteFindServerPath:
@@ -695,9 +707,13 @@ static int
 static int
 remoteOpen (virConnectPtr conn, const char *uri_str, int flags)
 {
-    struct private_data *priv = malloc (sizeof(struct private_data));
+    struct private_data *priv;
     int ret, rflags = 0;
 
+    if (inside_daemon)
+        return VIR_DRV_OPEN_DECLINED;
+
+    priv = malloc (sizeof(struct private_data));
     if (!priv) {
         error (NULL, VIR_ERR_NO_MEMORY, "struct private_data");
         return VIR_DRV_OPEN_ERROR;
@@ -2361,6 +2377,9 @@ remoteNetworkOpen (virConnectPtr conn,
                    const char *uri_str,
                    int flags)
 {
+    if (inside_daemon)
+        return VIR_DRV_OPEN_DECLINED;
+
     if (conn &&
         conn->driver &&
         strcmp (conn->driver->name, "remote") == 0) {
@@ -3174,6 +3193,14 @@ static virNetworkDriver network_driver =
     .networkSetAutostart = remoteNetworkSetAutostart,
 };
 
+static virStateDriver state_driver = {
+    remoteStartup,
+    NULL,
+    NULL,
+    NULL,
+};
+
+
 /** remoteRegister:
  *
  * Register driver with libvirt driver system.
@@ -3185,6 +3212,7 @@ remoteRegister (void)
 {
     if (virRegisterDriver (&driver) == -1) return -1;
     if (virRegisterNetworkDriver (&network_driver) == -1) return -1;
+    if (virRegisterStateDriver (&state_driver) == -1) return -1;
 
     return 0;
 }


More information about the libvir-list mailing list