From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> 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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list