From: "Daniel P. Berrange" <berrange(a)redhat.com>
Update the LXC driver to use the virNetClient APIs for
connecting to the libvirt_lxc monitor, instead of the
low-level socket APIs. This is a step towards running
a full RPC protocol with libvirt_lxc
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/lxc/lxc_domain.c | 3 -
src/lxc/lxc_domain.h | 5 +-
src/lxc/lxc_process.c | 162 +++++++++++++++++--------------------------------
3 files changed, 59 insertions(+), 111 deletions(-)
diff --git a/src/lxc/lxc_domain.c b/src/lxc/lxc_domain.c
index 847aac7..2ce2a18 100644
--- a/src/lxc/lxc_domain.c
+++ b/src/lxc/lxc_domain.c
@@ -32,9 +32,6 @@ static void *virLXCDomainObjPrivateAlloc(void)
if (VIR_ALLOC(priv) < 0)
return NULL;
- priv->monitor = -1;
- priv->monitorWatch = -1;
-
return priv;
}
diff --git a/src/lxc/lxc_domain.h b/src/lxc/lxc_domain.h
index 8a2c892..799248d 100644
--- a/src/lxc/lxc_domain.h
+++ b/src/lxc/lxc_domain.h
@@ -24,12 +24,13 @@
# define __LXC_DOMAIN_H__
# include "lxc_conf.h"
+# include "rpc/virnetclient.h"
+
typedef struct _virLXCDomainObjPrivate virLXCDomainObjPrivate;
typedef virLXCDomainObjPrivate *virLXCDomainObjPrivatePtr;
struct _virLXCDomainObjPrivate {
- int monitor;
- int monitorWatch;
+ virNetClientPtr monitor;
};
void virLXCDomainSetPrivateDataHooks(virCapsPtr caps);
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index de11725..3a1959f 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -178,8 +178,9 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
/* Stop autodestroy in case guest is restarted */
virLXCProcessAutoDestroyRemove(driver, vm);
- virEventRemoveHandle(priv->monitorWatch);
- VIR_FORCE_CLOSE(priv->monitor);
+ virNetClientClose(priv->monitor);
+ virNetClientFree(priv->monitor);
+ priv->monitor = NULL;
virPidFileDelete(driver->stateDir, vm->def->name);
virDomainDeleteConfig(driver->stateDir, NULL, vm);
@@ -187,8 +188,6 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
vm->pid = -1;
vm->def->id = -1;
- priv->monitor = -1;
- priv->monitorWatch = -1;
for (i = 0 ; i < vm->def->nnets ; i++) {
virDomainNetDefPtr iface = vm->def->nets[i];
@@ -472,60 +471,70 @@ cleanup:
}
-static int virLXCProcessMonitorClient(virLXCDriverPtr driver,
- virDomainObjPtr vm)
+extern virLXCDriverPtr lxc_driver;
+static void virLXCProcessMonitorEOFNotify(virNetClientPtr client ATTRIBUTE_UNUSED,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ virLXCDriverPtr driver = lxc_driver;
+ virDomainObjPtr vm = opaque;
+ virDomainEventPtr event = NULL;
+
+ lxcDriverLock(driver);
+ virDomainObjLock(vm);
+ lxcDriverUnlock(driver);
+
+ virLXCProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
+ event = virDomainEventNewFromObj(vm,
+ VIR_DOMAIN_EVENT_STOPPED,
+ VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
+ virDomainAuditStop(vm, "shutdown");
+ if (!vm->persistent) {
+ virDomainRemoveInactive(&driver->domains, vm);
+ vm = NULL;
+ }
+
+ if (vm)
+ virDomainObjUnlock(vm);
+ if (event) {
+ lxcDriverLock(driver);
+ virDomainEventStateQueue(driver->domainEventState, event);
+ lxcDriverUnlock(driver);
+ }
+}
+
+
+static virNetClientPtr virLXCProcessConnectMonitor(virLXCDriverPtr driver,
+ virDomainObjPtr vm)
{
char *sockpath = NULL;
- int fd = -1;
- struct sockaddr_un addr;
+ virNetClientPtr monitor = NULL;
if (virAsprintf(&sockpath, "%s/%s.sock",
driver->stateDir, vm->def->name) < 0) {
virReportOOMError();
- return -1;
+ return NULL;
}
- if (virSecurityManagerSetSocketLabel(driver->securityManager, vm->def) < 0)
{
- VIR_ERROR(_("Failed to set security context for monitor for %s"),
- vm->def->name);
- goto error;
- }
+ if (virSecurityManagerSetSocketLabel(driver->securityManager, vm->def) < 0)
+ goto cleanup;
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ monitor = virNetClientNewUNIX(sockpath, false, NULL);
if (virSecurityManagerClearSocketLabel(driver->securityManager, vm->def) <
0) {
- VIR_ERROR(_("Failed to clear security context for monitor for %s"),
- vm->def->name);
- goto error;
- }
-
- if (fd < 0) {
- virReportSystemError(errno, "%s",
- _("Failed to create client socket"));
- goto error;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- if (virStrcpyStatic(addr.sun_path, sockpath) == NULL) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Socket path %s too big for destination"), sockpath);
- goto error;
+ virNetClientFree(monitor);
+ monitor = NULL;
+ goto cleanup;
}
- if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- virReportSystemError(errno, "%s",
- _("Failed to connect to client socket"));
- goto error;
- }
+ if (!monitor)
+ goto cleanup;
- VIR_FREE(sockpath);
- return fd;
+ virNetClientSetCloseCallback(monitor, virLXCProcessMonitorEOFNotify, vm, NULL);
-error:
+cleanup:
VIR_FREE(sockpath);
- VIR_FORCE_CLOSE(fd);
- return -1;
+ return monitor;
}
@@ -581,51 +590,6 @@ cleanup:
return rc;
}
-extern virLXCDriverPtr lxc_driver;
-static void virLXCProcessMonitorEvent(int watch,
- int fd,
- int events ATTRIBUTE_UNUSED,
- void *data)
-{
- virLXCDriverPtr driver = lxc_driver;
- virDomainObjPtr vm = data;
- virDomainEventPtr event = NULL;
- virLXCDomainObjPrivatePtr priv;
-
- lxcDriverLock(driver);
- virDomainObjLock(vm);
- lxcDriverUnlock(driver);
-
- priv = vm->privateData;
-
- if (priv->monitor != fd || priv->monitorWatch != watch) {
- virEventRemoveHandle(watch);
- goto cleanup;
- }
-
- if (virLXCProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN) < 0) {
- virEventRemoveHandle(watch);
- } else {
- event = virDomainEventNewFromObj(vm,
- VIR_DOMAIN_EVENT_STOPPED,
- VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
- virDomainAuditStop(vm, "shutdown");
- }
- if (!vm->persistent) {
- virDomainRemoveInactive(&driver->domains, vm);
- vm = NULL;
- }
-
-cleanup:
- if (vm)
- virDomainObjUnlock(vm);
- if (event) {
- lxcDriverLock(driver);
- virDomainEventStateQueue(driver->domainEventState, event);
- lxcDriverUnlock(driver);
- }
-}
-
static virCommandPtr
virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
@@ -1003,7 +967,7 @@ int virLXCProcessStart(virConnectPtr conn,
/* Connect to the controller as a client *first* because
* this will block until the child has written their
* pid file out to disk */
- if ((priv->monitor = virLXCProcessMonitorClient(driver, vm)) < 0)
+ if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
goto cleanup;
/* And get its pid */
@@ -1028,14 +992,6 @@ int virLXCProcessStart(virConnectPtr conn,
goto error;
}
- if ((priv->monitorWatch = virEventAddHandle(
- priv->monitor,
- VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
- virLXCProcessMonitorEvent,
- vm, NULL)) < 0) {
- goto error;
- }
-
if (autoDestroy &&
virLXCProcessAutoDestroyAdd(driver, vm, conn) < 0)
goto error;
@@ -1085,7 +1041,9 @@ cleanup:
VIR_FREE(veths[i]);
}
if (rc != 0) {
- VIR_FORCE_CLOSE(priv->monitor);
+ virNetClientClose(priv->monitor);
+ virNetClientFree(priv->monitor);
+ priv->monitor = NULL;
virDomainConfVMNWFilterTeardown(vm);
virSecurityManagerRestoreAllLabel(driver->securityManager,
@@ -1191,14 +1149,7 @@ virLXCProcessReconnectDomain(void *payload, const void *name
ATTRIBUTE_UNUSED, v
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
VIR_DOMAIN_RUNNING_UNKNOWN);
- if ((priv->monitor = virLXCProcessMonitorClient(driver, vm)) < 0)
- goto error;
-
- if ((priv->monitorWatch = virEventAddHandle(
- priv->monitor,
- VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
- virLXCProcessMonitorEvent,
- vm, NULL)) < 0)
+ if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
goto error;
if (virSecurityManagerReserveLabel(driver->securityManager,
@@ -1221,7 +1172,6 @@ virLXCProcessReconnectDomain(void *payload, const void *name
ATTRIBUTE_UNUSED, v
} else {
vm->def->id = -1;
- VIR_FORCE_CLOSE(priv->monitor);
}
cleanup:
--
1.7.10.4