mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-18 18:45:16 +00:00
Convert the LXC driver to use virNetClient
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@redhat.com>
This commit is contained in:
parent
4343fee0a8
commit
357866c379
@ -32,9 +32,6 @@ static void *virLXCDomainObjPrivateAlloc(void)
|
|||||||
if (VIR_ALLOC(priv) < 0)
|
if (VIR_ALLOC(priv) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
priv->monitor = -1;
|
|
||||||
priv->monitorWatch = -1;
|
|
||||||
|
|
||||||
return priv;
|
return priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,12 +24,14 @@
|
|||||||
# define __LXC_DOMAIN_H__
|
# define __LXC_DOMAIN_H__
|
||||||
|
|
||||||
# include "lxc_conf.h"
|
# include "lxc_conf.h"
|
||||||
|
# include "rpc/virnetclient.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct _virLXCDomainObjPrivate virLXCDomainObjPrivate;
|
typedef struct _virLXCDomainObjPrivate virLXCDomainObjPrivate;
|
||||||
typedef virLXCDomainObjPrivate *virLXCDomainObjPrivatePtr;
|
typedef virLXCDomainObjPrivate *virLXCDomainObjPrivatePtr;
|
||||||
struct _virLXCDomainObjPrivate {
|
struct _virLXCDomainObjPrivate {
|
||||||
int monitor;
|
virNetClientPtr monitor;
|
||||||
int monitorWatch;
|
bool doneStopEvent;
|
||||||
};
|
};
|
||||||
|
|
||||||
void virLXCDomainSetPrivateDataHooks(virCapsPtr caps);
|
void virLXCDomainSetPrivateDataHooks(virCapsPtr caps);
|
||||||
|
@ -1276,6 +1276,7 @@ lxcDomainDestroyFlags(virDomainPtr dom,
|
|||||||
virDomainObjPtr vm;
|
virDomainObjPtr vm;
|
||||||
virDomainEventPtr event = NULL;
|
virDomainEventPtr event = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
virLXCDomainObjPrivatePtr priv;
|
||||||
|
|
||||||
virCheckFlags(0, -1);
|
virCheckFlags(0, -1);
|
||||||
|
|
||||||
@ -1295,10 +1296,12 @@ lxcDomainDestroyFlags(virDomainPtr dom,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv = vm->privateData;
|
||||||
ret = virLXCProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED);
|
ret = virLXCProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED);
|
||||||
event = virDomainEventNewFromObj(vm,
|
event = virDomainEventNewFromObj(vm,
|
||||||
VIR_DOMAIN_EVENT_STOPPED,
|
VIR_DOMAIN_EVENT_STOPPED,
|
||||||
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
|
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
|
||||||
|
priv->doneStopEvent = true;
|
||||||
virDomainAuditStop(vm, "destroyed");
|
virDomainAuditStop(vm, "destroyed");
|
||||||
if (!vm->persistent) {
|
if (!vm->persistent) {
|
||||||
virDomainRemoveInactive(&driver->domains, vm);
|
virDomainRemoveInactive(&driver->domains, vm);
|
||||||
|
@ -71,6 +71,7 @@ static void virLXCProcessAutoDestroyDom(void *payload,
|
|||||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||||
virDomainObjPtr dom;
|
virDomainObjPtr dom;
|
||||||
virDomainEventPtr event = NULL;
|
virDomainEventPtr event = NULL;
|
||||||
|
virLXCDomainObjPrivatePtr priv;
|
||||||
|
|
||||||
VIR_DEBUG("conn=%p uuidstr=%s thisconn=%p", conn, uuidstr, data->conn);
|
VIR_DEBUG("conn=%p uuidstr=%s thisconn=%p", conn, uuidstr, data->conn);
|
||||||
|
|
||||||
@ -88,12 +89,14 @@ static void virLXCProcessAutoDestroyDom(void *payload,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv = dom->privateData;
|
||||||
VIR_DEBUG("Killing domain");
|
VIR_DEBUG("Killing domain");
|
||||||
virLXCProcessStop(data->driver, dom, VIR_DOMAIN_SHUTOFF_DESTROYED);
|
virLXCProcessStop(data->driver, dom, VIR_DOMAIN_SHUTOFF_DESTROYED);
|
||||||
virDomainAuditStop(dom, "destroyed");
|
virDomainAuditStop(dom, "destroyed");
|
||||||
event = virDomainEventNewFromObj(dom,
|
event = virDomainEventNewFromObj(dom,
|
||||||
VIR_DOMAIN_EVENT_STOPPED,
|
VIR_DOMAIN_EVENT_STOPPED,
|
||||||
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
|
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
|
||||||
|
priv->doneStopEvent = true;
|
||||||
|
|
||||||
if (dom && !dom->persistent)
|
if (dom && !dom->persistent)
|
||||||
virDomainRemoveInactive(&data->driver->domains, dom);
|
virDomainRemoveInactive(&data->driver->domains, dom);
|
||||||
@ -178,8 +181,9 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
|
|||||||
/* Stop autodestroy in case guest is restarted */
|
/* Stop autodestroy in case guest is restarted */
|
||||||
virLXCProcessAutoDestroyRemove(driver, vm);
|
virLXCProcessAutoDestroyRemove(driver, vm);
|
||||||
|
|
||||||
virEventRemoveHandle(priv->monitorWatch);
|
virNetClientClose(priv->monitor);
|
||||||
VIR_FORCE_CLOSE(priv->monitor);
|
virNetClientFree(priv->monitor);
|
||||||
|
priv->monitor = NULL;
|
||||||
|
|
||||||
virPidFileDelete(driver->stateDir, vm->def->name);
|
virPidFileDelete(driver->stateDir, vm->def->name);
|
||||||
virDomainDeleteConfig(driver->stateDir, NULL, vm);
|
virDomainDeleteConfig(driver->stateDir, NULL, vm);
|
||||||
@ -187,8 +191,6 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
|
|||||||
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
|
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
|
||||||
vm->pid = -1;
|
vm->pid = -1;
|
||||||
vm->def->id = -1;
|
vm->def->id = -1;
|
||||||
priv->monitor = -1;
|
|
||||||
priv->monitorWatch = -1;
|
|
||||||
|
|
||||||
for (i = 0 ; i < vm->def->nnets ; i++) {
|
for (i = 0 ; i < vm->def->nnets ; i++) {
|
||||||
virDomainNetDefPtr iface = vm->def->nets[i];
|
virDomainNetDefPtr iface = vm->def->nets[i];
|
||||||
@ -472,60 +474,76 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int virLXCProcessMonitorClient(virLXCDriverPtr driver,
|
extern virLXCDriverPtr lxc_driver;
|
||||||
virDomainObjPtr vm)
|
static void virLXCProcessMonitorEOFNotify(virNetClientPtr client ATTRIBUTE_UNUSED,
|
||||||
|
int reason ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
virLXCDriverPtr driver = lxc_driver;
|
||||||
|
virDomainObjPtr vm = opaque;
|
||||||
|
virDomainEventPtr event = NULL;
|
||||||
|
virLXCDomainObjPrivatePtr priv;
|
||||||
|
|
||||||
|
lxcDriverLock(driver);
|
||||||
|
virDomainObjLock(vm);
|
||||||
|
lxcDriverUnlock(driver);
|
||||||
|
|
||||||
|
priv = vm->privateData;
|
||||||
|
virLXCProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
|
||||||
|
if (!priv->doneStopEvent) {
|
||||||
|
event = virDomainEventNewFromObj(vm,
|
||||||
|
VIR_DOMAIN_EVENT_STOPPED,
|
||||||
|
VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
|
||||||
|
virDomainAuditStop(vm, "shutdown");
|
||||||
|
} else {
|
||||||
|
VIR_DEBUG("Stop event has already been sent");
|
||||||
|
}
|
||||||
|
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;
|
char *sockpath = NULL;
|
||||||
int fd = -1;
|
virNetClientPtr monitor = NULL;
|
||||||
struct sockaddr_un addr;
|
|
||||||
|
|
||||||
if (virAsprintf(&sockpath, "%s/%s.sock",
|
if (virAsprintf(&sockpath, "%s/%s.sock",
|
||||||
driver->stateDir, vm->def->name) < 0) {
|
driver->stateDir, vm->def->name) < 0) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virSecurityManagerSetSocketLabel(driver->securityManager, vm->def) < 0) {
|
if (virSecurityManagerSetSocketLabel(driver->securityManager, vm->def) < 0)
|
||||||
VIR_ERROR(_("Failed to set security context for monitor for %s"),
|
goto cleanup;
|
||||||
vm->def->name);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
monitor = virNetClientNewUNIX(sockpath, false, NULL);
|
||||||
|
|
||||||
if (virSecurityManagerClearSocketLabel(driver->securityManager, vm->def) < 0) {
|
if (virSecurityManagerClearSocketLabel(driver->securityManager, vm->def) < 0) {
|
||||||
VIR_ERROR(_("Failed to clear security context for monitor for %s"),
|
virNetClientFree(monitor);
|
||||||
vm->def->name);
|
monitor = NULL;
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd < 0) {
|
if (!monitor)
|
||||||
virReportSystemError(errno, "%s",
|
goto cleanup;
|
||||||
_("Failed to create client socket"));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
virNetClientSetCloseCallback(monitor, virLXCProcessMonitorEOFNotify, vm, NULL);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
|
||||||
virReportSystemError(errno, "%s",
|
|
||||||
_("Failed to connect to client socket"));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
cleanup:
|
||||||
VIR_FREE(sockpath);
|
VIR_FREE(sockpath);
|
||||||
return fd;
|
return monitor;
|
||||||
|
|
||||||
error:
|
|
||||||
VIR_FREE(sockpath);
|
|
||||||
VIR_FORCE_CLOSE(fd);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -581,51 +599,6 @@ cleanup:
|
|||||||
return rc;
|
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
|
static virCommandPtr
|
||||||
virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
|
virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
|
||||||
@ -1003,7 +976,7 @@ int virLXCProcessStart(virConnectPtr conn,
|
|||||||
/* Connect to the controller as a client *first* because
|
/* Connect to the controller as a client *first* because
|
||||||
* this will block until the child has written their
|
* this will block until the child has written their
|
||||||
* pid file out to disk */
|
* pid file out to disk */
|
||||||
if ((priv->monitor = virLXCProcessMonitorClient(driver, vm)) < 0)
|
if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* And get its pid */
|
/* And get its pid */
|
||||||
@ -1016,6 +989,7 @@ int virLXCProcessStart(virConnectPtr conn,
|
|||||||
|
|
||||||
vm->def->id = vm->pid;
|
vm->def->id = vm->pid;
|
||||||
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
|
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
|
||||||
|
priv->doneStopEvent = false;
|
||||||
|
|
||||||
if (lxcContainerWaitForContinue(handshakefds[0]) < 0) {
|
if (lxcContainerWaitForContinue(handshakefds[0]) < 0) {
|
||||||
char out[1024];
|
char out[1024];
|
||||||
@ -1028,14 +1002,6 @@ int virLXCProcessStart(virConnectPtr conn,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((priv->monitorWatch = virEventAddHandle(
|
|
||||||
priv->monitor,
|
|
||||||
VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
|
|
||||||
virLXCProcessMonitorEvent,
|
|
||||||
vm, NULL)) < 0) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (autoDestroy &&
|
if (autoDestroy &&
|
||||||
virLXCProcessAutoDestroyAdd(driver, vm, conn) < 0)
|
virLXCProcessAutoDestroyAdd(driver, vm, conn) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -1085,7 +1051,9 @@ cleanup:
|
|||||||
VIR_FREE(veths[i]);
|
VIR_FREE(veths[i]);
|
||||||
}
|
}
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
VIR_FORCE_CLOSE(priv->monitor);
|
virNetClientClose(priv->monitor);
|
||||||
|
virNetClientFree(priv->monitor);
|
||||||
|
priv->monitor = NULL;
|
||||||
virDomainConfVMNWFilterTeardown(vm);
|
virDomainConfVMNWFilterTeardown(vm);
|
||||||
|
|
||||||
virSecurityManagerRestoreAllLabel(driver->securityManager,
|
virSecurityManagerRestoreAllLabel(driver->securityManager,
|
||||||
@ -1191,14 +1159,7 @@ virLXCProcessReconnectDomain(void *payload, const void *name ATTRIBUTE_UNUSED, v
|
|||||||
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
|
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
|
||||||
VIR_DOMAIN_RUNNING_UNKNOWN);
|
VIR_DOMAIN_RUNNING_UNKNOWN);
|
||||||
|
|
||||||
if ((priv->monitor = virLXCProcessMonitorClient(driver, vm)) < 0)
|
if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
|
||||||
goto error;
|
|
||||||
|
|
||||||
if ((priv->monitorWatch = virEventAddHandle(
|
|
||||||
priv->monitor,
|
|
||||||
VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
|
|
||||||
virLXCProcessMonitorEvent,
|
|
||||||
vm, NULL)) < 0)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (virSecurityManagerReserveLabel(driver->securityManager,
|
if (virSecurityManagerReserveLabel(driver->securityManager,
|
||||||
@ -1221,7 +1182,6 @@ virLXCProcessReconnectDomain(void *payload, const void *name ATTRIBUTE_UNUSED, v
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
vm->def->id = -1;
|
vm->def->id = -1;
|
||||||
VIR_FORCE_CLOSE(priv->monitor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user