mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-29 00:55:22 +00:00
Replace polling for active VMs with signalling by drivers
Currently to deal with auto-shutdown libvirtd must periodically poll all stateful drivers. Thus sucks because it requires acquiring both the driver lock and locks on every single virtual machine. Instead pass in a "inhibit" callback to virStateInitialize which drivers can invoke whenever they want to inhibit shutdown due to existance of active VMs. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
ae2163f852
commit
79b8a56995
@ -584,16 +584,6 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int daemonShutdownCheck(virNetServerPtr srv ATTRIBUTE_UNUSED,
|
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
if (virStateActive())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the logging environment
|
* Set up the logging environment
|
||||||
* By default if daemonized all errors go to the logfile libvirtd.log,
|
* By default if daemonized all errors go to the logfile libvirtd.log,
|
||||||
@ -772,6 +762,18 @@ static int daemonSetupSignals(virNetServerPtr srv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void daemonInhibitCallback(bool inhibit, void *opaque)
|
||||||
|
{
|
||||||
|
virNetServerPtr srv = opaque;
|
||||||
|
|
||||||
|
if (inhibit)
|
||||||
|
virNetServerAddShutdownInhibition(srv);
|
||||||
|
else
|
||||||
|
virNetServerRemoveShutdownInhibition(srv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void daemonRunStateInit(void *opaque)
|
static void daemonRunStateInit(void *opaque)
|
||||||
{
|
{
|
||||||
virNetServerPtr srv = opaque;
|
virNetServerPtr srv = opaque;
|
||||||
@ -780,7 +782,9 @@ static void daemonRunStateInit(void *opaque)
|
|||||||
* This is deliberately done after telling the parent process
|
* This is deliberately done after telling the parent process
|
||||||
* we're ready, since it can take a long time and this will
|
* we're ready, since it can take a long time and this will
|
||||||
* seriously delay OS bootup process */
|
* seriously delay OS bootup process */
|
||||||
if (virStateInitialize(virNetServerIsPrivileged(srv)) < 0) {
|
if (virStateInitialize(virNetServerIsPrivileged(srv),
|
||||||
|
daemonInhibitCallback,
|
||||||
|
srv) < 0) {
|
||||||
VIR_ERROR(_("Driver state initialization failed"));
|
VIR_ERROR(_("Driver state initialization failed"));
|
||||||
/* Ensure the main event loop quits */
|
/* Ensure the main event loop quits */
|
||||||
kill(getpid(), SIGTERM);
|
kill(getpid(), SIGTERM);
|
||||||
@ -1270,9 +1274,7 @@ int main(int argc, char **argv) {
|
|||||||
if (timeout != -1) {
|
if (timeout != -1) {
|
||||||
VIR_DEBUG("Registering shutdown timeout %d", timeout);
|
VIR_DEBUG("Registering shutdown timeout %d", timeout);
|
||||||
virNetServerAutoShutdown(srv,
|
virNetServerAutoShutdown(srv,
|
||||||
timeout,
|
timeout);
|
||||||
daemonShutdownCheck,
|
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((daemonSetupSignals(srv)) < 0) {
|
if ((daemonSetupSignals(srv)) < 0) {
|
||||||
|
@ -1603,12 +1603,14 @@ libvirt_net_rpc_server_la_SOURCES = \
|
|||||||
rpc/virnetserver.h rpc/virnetserver.c
|
rpc/virnetserver.h rpc/virnetserver.c
|
||||||
libvirt_net_rpc_server_la_CFLAGS = \
|
libvirt_net_rpc_server_la_CFLAGS = \
|
||||||
$(AVAHI_CFLAGS) \
|
$(AVAHI_CFLAGS) \
|
||||||
|
$(DBUS_CFLAGS) \
|
||||||
$(XDR_CFLAGS) \
|
$(XDR_CFLAGS) \
|
||||||
$(AM_CFLAGS) \
|
$(AM_CFLAGS) \
|
||||||
$(POLKIT_CFLAGS)
|
$(POLKIT_CFLAGS)
|
||||||
libvirt_net_rpc_server_la_LDFLAGS = \
|
libvirt_net_rpc_server_la_LDFLAGS = \
|
||||||
$(AM_LDFLAGS) \
|
$(AM_LDFLAGS) \
|
||||||
$(AVAHI_LIBS) \
|
$(AVAHI_LIBS) \
|
||||||
|
$(DBUS_LIBS) \
|
||||||
$(POLKIT_LIBS) \
|
$(POLKIT_LIBS) \
|
||||||
$(CYGWIN_EXTRA_LDFLAGS) \
|
$(CYGWIN_EXTRA_LDFLAGS) \
|
||||||
$(MINGW_EXTRA_LDFLAGS)
|
$(MINGW_EXTRA_LDFLAGS)
|
||||||
|
@ -1500,10 +1500,12 @@ struct _virStorageDriver {
|
|||||||
};
|
};
|
||||||
|
|
||||||
# ifdef WITH_LIBVIRTD
|
# ifdef WITH_LIBVIRTD
|
||||||
typedef int (*virDrvStateInitialize) (bool privileged);
|
|
||||||
|
typedef int (*virDrvStateInitialize) (bool privileged,
|
||||||
|
virStateInhibitCallback callback,
|
||||||
|
void *opaque);
|
||||||
typedef int (*virDrvStateCleanup) (void);
|
typedef int (*virDrvStateCleanup) (void);
|
||||||
typedef int (*virDrvStateReload) (void);
|
typedef int (*virDrvStateReload) (void);
|
||||||
typedef int (*virDrvStateActive) (void);
|
|
||||||
typedef int (*virDrvStateStop) (void);
|
typedef int (*virDrvStateStop) (void);
|
||||||
|
|
||||||
typedef struct _virStateDriver virStateDriver;
|
typedef struct _virStateDriver virStateDriver;
|
||||||
@ -1514,7 +1516,6 @@ struct _virStateDriver {
|
|||||||
virDrvStateInitialize initialize;
|
virDrvStateInitialize initialize;
|
||||||
virDrvStateCleanup cleanup;
|
virDrvStateCleanup cleanup;
|
||||||
virDrvStateReload reload;
|
virDrvStateReload reload;
|
||||||
virDrvStateActive active;
|
|
||||||
virDrvStateStop stop;
|
virDrvStateStop stop;
|
||||||
};
|
};
|
||||||
# endif
|
# endif
|
||||||
|
@ -790,12 +790,17 @@ virRegisterStateDriver(virStateDriverPtr driver)
|
|||||||
/**
|
/**
|
||||||
* virStateInitialize:
|
* virStateInitialize:
|
||||||
* @privileged: set to true if running with root privilege, false otherwise
|
* @privileged: set to true if running with root privilege, false otherwise
|
||||||
|
* @callback: callback to invoke to inhibit shutdown of the daemon
|
||||||
|
* @opaque: data to pass to @callback
|
||||||
*
|
*
|
||||||
* Initialize all virtualization drivers.
|
* Initialize all virtualization drivers.
|
||||||
*
|
*
|
||||||
* Returns 0 if all succeed, -1 upon any failure.
|
* Returns 0 if all succeed, -1 upon any failure.
|
||||||
*/
|
*/
|
||||||
int virStateInitialize(bool privileged) {
|
int virStateInitialize(bool privileged,
|
||||||
|
virStateInhibitCallback callback,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (virInitialize() < 0)
|
if (virInitialize() < 0)
|
||||||
@ -805,7 +810,9 @@ int virStateInitialize(bool privileged) {
|
|||||||
if (virStateDriverTab[i]->initialize) {
|
if (virStateDriverTab[i]->initialize) {
|
||||||
VIR_DEBUG("Running global init for %s state driver",
|
VIR_DEBUG("Running global init for %s state driver",
|
||||||
virStateDriverTab[i]->name);
|
virStateDriverTab[i]->name);
|
||||||
if (virStateDriverTab[i]->initialize(privileged) < 0) {
|
if (virStateDriverTab[i]->initialize(privileged,
|
||||||
|
callback,
|
||||||
|
opaque) < 0) {
|
||||||
VIR_ERROR(_("Initialization of %s state driver failed"),
|
VIR_ERROR(_("Initialization of %s state driver failed"),
|
||||||
virStateDriverTab[i]->name);
|
virStateDriverTab[i]->name);
|
||||||
return -1;
|
return -1;
|
||||||
@ -851,24 +858,6 @@ int virStateReload(void) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* virStateActive:
|
|
||||||
*
|
|
||||||
* Run each virtualization driver's "active" method.
|
|
||||||
*
|
|
||||||
* Returns 0 if none are active, 1 if at least one is.
|
|
||||||
*/
|
|
||||||
int virStateActive(void) {
|
|
||||||
int i, ret = 0;
|
|
||||||
|
|
||||||
for (i = 0 ; i < virStateDriverTabCount ; i++) {
|
|
||||||
if (virStateDriverTab[i]->active &&
|
|
||||||
virStateDriverTab[i]->active())
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virStateStop:
|
* virStateStop:
|
||||||
*
|
*
|
||||||
|
@ -28,10 +28,14 @@
|
|||||||
# include "internal.h"
|
# include "internal.h"
|
||||||
|
|
||||||
# ifdef WITH_LIBVIRTD
|
# ifdef WITH_LIBVIRTD
|
||||||
int virStateInitialize(bool privileged);
|
typedef void (*virStateInhibitCallback)(bool inhibit,
|
||||||
|
void *opaque);
|
||||||
|
|
||||||
|
int virStateInitialize(bool privileged,
|
||||||
|
virStateInhibitCallback inhibit,
|
||||||
|
void *opaque);
|
||||||
int virStateCleanup(void);
|
int virStateCleanup(void);
|
||||||
int virStateReload(void);
|
int virStateReload(void);
|
||||||
int virStateActive(void);
|
|
||||||
int virStateStop(void);
|
int virStateStop(void);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
@ -1595,6 +1595,7 @@ xdr_virNetMessageError;
|
|||||||
# virnetserver.h
|
# virnetserver.h
|
||||||
virNetServerAddProgram;
|
virNetServerAddProgram;
|
||||||
virNetServerAddService;
|
virNetServerAddService;
|
||||||
|
virNetServerAddShutdownInhibition;
|
||||||
virNetServerAddSignalHandler;
|
virNetServerAddSignalHandler;
|
||||||
virNetServerAutoShutdown;
|
virNetServerAutoShutdown;
|
||||||
virNetServerClose;
|
virNetServerClose;
|
||||||
@ -1604,6 +1605,7 @@ virNetServerNew;
|
|||||||
virNetServerNewPostExecRestart;
|
virNetServerNewPostExecRestart;
|
||||||
virNetServerPreExecRestart;
|
virNetServerPreExecRestart;
|
||||||
virNetServerQuit;
|
virNetServerQuit;
|
||||||
|
virNetServerRemoveShutdownInhibition;
|
||||||
virNetServerRun;
|
virNetServerRun;
|
||||||
virNetServerSetTLSContext;
|
virNetServerSetTLSContext;
|
||||||
virNetServerUpdateServices;
|
virNetServerUpdateServices;
|
||||||
|
@ -61,6 +61,11 @@ struct _libxlDriverPrivate {
|
|||||||
libxl_ctx ctx;
|
libxl_ctx ctx;
|
||||||
|
|
||||||
virBitmapPtr reservedVNCPorts;
|
virBitmapPtr reservedVNCPorts;
|
||||||
|
|
||||||
|
size_t nactive;
|
||||||
|
virStateInhibitCallback inhibitCallback;
|
||||||
|
void *inhibitOpaque;
|
||||||
|
|
||||||
virDomainObjList domains;
|
virDomainObjList domains;
|
||||||
|
|
||||||
virDomainEventStatePtr domainEventState;
|
virDomainEventStatePtr domainEventState;
|
||||||
|
@ -312,6 +312,10 @@ libxlVmCleanup(libxlDriverPrivatePtr driver,
|
|||||||
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
|
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
driver->nactive--;
|
||||||
|
if (!driver->nactive && driver->inhibitCallback)
|
||||||
|
driver->inhibitCallback(false, driver->inhibitOpaque);
|
||||||
|
|
||||||
if ((vm->def->ngraphics == 1) &&
|
if ((vm->def->ngraphics == 1) &&
|
||||||
vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
|
vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
|
||||||
vm->def->graphics[0]->data.vnc.autoport) {
|
vm->def->graphics[0]->data.vnc.autoport) {
|
||||||
@ -717,6 +721,10 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
|
|||||||
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
|
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (!driver->nactive && driver->inhibitCallback)
|
||||||
|
driver->inhibitCallback(true, driver->inhibitOpaque);
|
||||||
|
driver->nactive++;
|
||||||
|
|
||||||
event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED,
|
event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED,
|
||||||
restore_fd < 0 ?
|
restore_fd < 0 ?
|
||||||
VIR_DOMAIN_EVENT_STARTED_BOOTED :
|
VIR_DOMAIN_EVENT_STARTED_BOOTED :
|
||||||
@ -782,6 +790,10 @@ libxlReconnectDomain(void *payload,
|
|||||||
vm->def->id = d_info.domid;
|
vm->def->id = d_info.domid;
|
||||||
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_UNKNOWN);
|
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_UNKNOWN);
|
||||||
|
|
||||||
|
if (!driver->nactive && driver->inhibitCallback)
|
||||||
|
driver->inhibitCallback(true, driver->inhibitOpaque);
|
||||||
|
driver->nactive++;
|
||||||
|
|
||||||
/* Recreate domain death et. al. events */
|
/* Recreate domain death et. al. events */
|
||||||
libxlCreateDomEvents(vm);
|
libxlCreateDomEvents(vm);
|
||||||
virDomainObjUnlock(vm);
|
virDomainObjUnlock(vm);
|
||||||
@ -834,7 +846,10 @@ libxlShutdown(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
libxlStartup(bool privileged) {
|
libxlStartup(bool privileged,
|
||||||
|
virStateInhibitCallback callback ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
const libxl_version_info *ver_info;
|
const libxl_version_info *ver_info;
|
||||||
char *log_file = NULL;
|
char *log_file = NULL;
|
||||||
virCommandPtr cmd;
|
virCommandPtr cmd;
|
||||||
@ -1030,14 +1045,6 @@ libxlReload(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
libxlActive(void)
|
|
||||||
{
|
|
||||||
if (!libxl_driver)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static virDrvOpenStatus
|
static virDrvOpenStatus
|
||||||
libxlOpen(virConnectPtr conn,
|
libxlOpen(virConnectPtr conn,
|
||||||
@ -3969,7 +3976,6 @@ static virStateDriver libxlStateDriver = {
|
|||||||
.initialize = libxlStartup,
|
.initialize = libxlStartup,
|
||||||
.cleanup = libxlShutdown,
|
.cleanup = libxlShutdown,
|
||||||
.reload = libxlReload,
|
.reload = libxlReload,
|
||||||
.active = libxlActive,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,6 +52,11 @@ struct _virLXCDriver {
|
|||||||
virCapsPtr caps;
|
virCapsPtr caps;
|
||||||
|
|
||||||
virCgroupPtr cgroup;
|
virCgroupPtr cgroup;
|
||||||
|
|
||||||
|
size_t nactive;
|
||||||
|
virStateInhibitCallback inhibitCallback;
|
||||||
|
void *inhibitOpaque;
|
||||||
|
|
||||||
virDomainObjList domains;
|
virDomainObjList domains;
|
||||||
char *configDir;
|
char *configDir;
|
||||||
char *autostartDir;
|
char *autostartDir;
|
||||||
|
@ -70,7 +70,9 @@
|
|||||||
|
|
||||||
#define LXC_NB_MEM_PARAM 3
|
#define LXC_NB_MEM_PARAM 3
|
||||||
|
|
||||||
static int lxcStartup(bool privileged);
|
static int lxcStartup(bool privileged,
|
||||||
|
virStateInhibitCallback callback,
|
||||||
|
void *opaque);
|
||||||
static int lxcShutdown(void);
|
static int lxcShutdown(void);
|
||||||
virLXCDriverPtr lxc_driver = NULL;
|
virLXCDriverPtr lxc_driver = NULL;
|
||||||
|
|
||||||
@ -1398,7 +1400,9 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int lxcStartup(bool privileged)
|
static int lxcStartup(bool privileged,
|
||||||
|
virStateInhibitCallback callback ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
char *ld;
|
char *ld;
|
||||||
int rc;
|
int rc;
|
||||||
@ -1564,26 +1568,6 @@ static int lxcShutdown(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* lxcActive:
|
|
||||||
*
|
|
||||||
* Checks if the LXC daemon is active, i.e. has an active domain
|
|
||||||
*
|
|
||||||
* Returns 1 if active, 0 otherwise
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
lxcActive(void) {
|
|
||||||
int active;
|
|
||||||
|
|
||||||
if (lxc_driver == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
lxcDriverLock(lxc_driver);
|
|
||||||
active = virDomainObjListNumOfDomains(&lxc_driver->domains, 1);
|
|
||||||
lxcDriverUnlock(lxc_driver);
|
|
||||||
|
|
||||||
return active;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int lxcVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *version)
|
static int lxcVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *version)
|
||||||
{
|
{
|
||||||
@ -3014,7 +2998,6 @@ static virStateDriver lxcStateDriver = {
|
|||||||
.name = LXC_DRIVER_NAME,
|
.name = LXC_DRIVER_NAME,
|
||||||
.initialize = lxcStartup,
|
.initialize = lxcStartup,
|
||||||
.cleanup = lxcShutdown,
|
.cleanup = lxcShutdown,
|
||||||
.active = lxcActive,
|
|
||||||
.reload = lxcReload,
|
.reload = lxcReload,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -252,6 +252,10 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
|
|||||||
vm->pid = -1;
|
vm->pid = -1;
|
||||||
vm->def->id = -1;
|
vm->def->id = -1;
|
||||||
|
|
||||||
|
driver->nactive--;
|
||||||
|
if (!driver->nactive && driver->inhibitCallback)
|
||||||
|
driver->inhibitCallback(false, driver->inhibitOpaque);
|
||||||
|
|
||||||
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];
|
||||||
vport = virDomainNetGetActualVirtPortProfile(iface);
|
vport = virDomainNetGetActualVirtPortProfile(iface);
|
||||||
@ -1139,6 +1143,10 @@ int virLXCProcessStart(virConnectPtr conn,
|
|||||||
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
|
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
|
||||||
priv->doneStopEvent = false;
|
priv->doneStopEvent = false;
|
||||||
|
|
||||||
|
if (!driver->nactive && driver->inhibitCallback)
|
||||||
|
driver->inhibitCallback(true, driver->inhibitOpaque);
|
||||||
|
driver->nactive++;
|
||||||
|
|
||||||
if (lxcContainerWaitForContinue(handshakefds[0]) < 0) {
|
if (lxcContainerWaitForContinue(handshakefds[0]) < 0) {
|
||||||
char out[1024];
|
char out[1024];
|
||||||
|
|
||||||
@ -1313,6 +1321,10 @@ 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 (!driver->nactive && driver->inhibitCallback)
|
||||||
|
driver->inhibitCallback(true, driver->inhibitOpaque);
|
||||||
|
driver->nactive++;
|
||||||
|
|
||||||
if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
|
if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -332,7 +332,10 @@ firewalld_dbus_filter_bridge(DBusConnection *connection ATTRIBUTE_UNUSED,
|
|||||||
* Initialization function for the QEmu daemon
|
* Initialization function for the QEmu daemon
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
networkStartup(bool privileged) {
|
networkStartup(bool privileged,
|
||||||
|
virStateInhibitCallback callback ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
char *base = NULL;
|
char *base = NULL;
|
||||||
#ifdef HAVE_FIREWALLD
|
#ifdef HAVE_FIREWALLD
|
||||||
DBusConnection *sysbus = NULL;
|
DBusConnection *sysbus = NULL;
|
||||||
|
@ -586,9 +586,9 @@ static void device_prop_modified(LibHalContext *ctx ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int halDeviceMonitorStartup(bool privileged ATTRIBUTE_UNUSED,
|
||||||
|
virStateInhibitCallback callback ATTRIBUTE_UNUSED,
|
||||||
static int halDeviceMonitorStartup(bool privileged ATTRIBUTE_UNUSED)
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
LibHalContext *hal_ctx = NULL;
|
LibHalContext *hal_ctx = NULL;
|
||||||
char **udi = NULL;
|
char **udi = NULL;
|
||||||
|
@ -1604,7 +1604,9 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int udevDeviceMonitorStartup(bool privileged ATTRIBUTE_UNUSED)
|
static int udevDeviceMonitorStartup(bool privileged ATTRIBUTE_UNUSED,
|
||||||
|
virStateInhibitCallback callback ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
udevPrivate *priv = NULL;
|
udevPrivate *priv = NULL;
|
||||||
struct udev *udev = NULL;
|
struct udev *udev = NULL;
|
||||||
|
@ -165,7 +165,9 @@ nwfilterDriverInstallDBusMatches(DBusConnection *sysbus ATTRIBUTE_UNUSED)
|
|||||||
* Initialization function for the QEmu daemon
|
* Initialization function for the QEmu daemon
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
nwfilterDriverStartup(bool privileged)
|
nwfilterDriverStartup(bool privileged ATTRIBUTE_UNUSED,
|
||||||
|
virStateInhibitCallback callback ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
char *base = NULL;
|
char *base = NULL;
|
||||||
DBusConnection *sysbus = NULL;
|
DBusConnection *sysbus = NULL;
|
||||||
|
@ -73,6 +73,10 @@ struct _virQEMUDriver {
|
|||||||
int cgroupControllers;
|
int cgroupControllers;
|
||||||
char **cgroupDeviceACL;
|
char **cgroupDeviceACL;
|
||||||
|
|
||||||
|
size_t nactive;
|
||||||
|
virStateInhibitCallback inhibitCallback;
|
||||||
|
void *inhibitOpaque;
|
||||||
|
|
||||||
virDomainObjList domains;
|
virDomainObjList domains;
|
||||||
|
|
||||||
/* These four directories are ones libvirtd uses (so must be root:root
|
/* These four directories are ones libvirtd uses (so must be root:root
|
||||||
|
@ -610,7 +610,10 @@ qemuDomainFindMaxID(void *payload,
|
|||||||
* Initialization function for the QEmu daemon
|
* Initialization function for the QEmu daemon
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
qemuStartup(bool privileged) {
|
qemuStartup(bool privileged,
|
||||||
|
virStateInhibitCallback callback,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
char *base = NULL;
|
char *base = NULL;
|
||||||
char *driverConf = NULL;
|
char *driverConf = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
@ -631,6 +634,8 @@ qemuStartup(bool privileged) {
|
|||||||
|
|
||||||
qemu_driver->privileged = privileged;
|
qemu_driver->privileged = privileged;
|
||||||
qemu_driver->uri = privileged ? "qemu:///system" : "qemu:///session";
|
qemu_driver->uri = privileged ? "qemu:///system" : "qemu:///session";
|
||||||
|
qemu_driver->inhibitCallback = callback;
|
||||||
|
qemu_driver->inhibitOpaque = opaque;
|
||||||
|
|
||||||
/* Don't have a dom0 so start from 1 */
|
/* Don't have a dom0 so start from 1 */
|
||||||
qemu_driver->nextvmid = 1;
|
qemu_driver->nextvmid = 1;
|
||||||
@ -974,28 +979,6 @@ qemuReload(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* qemuActive:
|
|
||||||
*
|
|
||||||
* Checks if the QEmu daemon is active, i.e. has an active domain or
|
|
||||||
* an active network
|
|
||||||
*
|
|
||||||
* Returns 1 if active, 0 otherwise
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
qemuActive(void) {
|
|
||||||
int active = 0;
|
|
||||||
|
|
||||||
if (!qemu_driver)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* XXX having to iterate here is not great because it requires many locks */
|
|
||||||
qemuDriverLock(qemu_driver);
|
|
||||||
active = virDomainObjListNumOfDomains(&qemu_driver->domains, 1);
|
|
||||||
qemuDriverUnlock(qemu_driver);
|
|
||||||
return active;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* qemuStop:
|
* qemuStop:
|
||||||
@ -15066,7 +15049,6 @@ static virStateDriver qemuStateDriver = {
|
|||||||
.initialize = qemuStartup,
|
.initialize = qemuStartup,
|
||||||
.cleanup = qemuShutdown,
|
.cleanup = qemuShutdown,
|
||||||
.reload = qemuReload,
|
.reload = qemuReload,
|
||||||
.active = qemuActive,
|
|
||||||
.stop = qemuStop,
|
.stop = qemuStop,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3228,6 +3228,10 @@ qemuProcessReconnect(void *opaque)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!driver->nactive && driver->inhibitCallback)
|
||||||
|
driver->inhibitCallback(true, driver->inhibitOpaque);
|
||||||
|
driver->nactive++;
|
||||||
|
|
||||||
endjob:
|
endjob:
|
||||||
if (!qemuDomainObjEndJob(driver, obj))
|
if (!qemuDomainObjEndJob(driver, obj))
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
@ -3436,6 +3440,10 @@ int qemuProcessStart(virConnectPtr conn,
|
|||||||
qemuDomainSetFakeReboot(driver, vm, false);
|
qemuDomainSetFakeReboot(driver, vm, false);
|
||||||
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_UNKNOWN);
|
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_UNKNOWN);
|
||||||
|
|
||||||
|
if (!driver->nactive && driver->inhibitCallback)
|
||||||
|
driver->inhibitCallback(true, driver->inhibitOpaque);
|
||||||
|
driver->nactive++;
|
||||||
|
|
||||||
/* Run an early hook to set-up missing devices */
|
/* Run an early hook to set-up missing devices */
|
||||||
if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
|
if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
|
||||||
char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
|
char *xml = qemuDomainDefFormatXML(driver, vm->def, 0);
|
||||||
@ -4002,6 +4010,10 @@ void qemuProcessStop(virQEMUDriverPtr driver,
|
|||||||
*/
|
*/
|
||||||
vm->def->id = -1;
|
vm->def->id = -1;
|
||||||
|
|
||||||
|
driver->nactive--;
|
||||||
|
if (!driver->nactive && driver->inhibitCallback)
|
||||||
|
driver->inhibitCallback(false, driver->inhibitOpaque);
|
||||||
|
|
||||||
if ((logfile = qemuDomainCreateLog(driver, vm, true)) < 0) {
|
if ((logfile = qemuDomainCreateLog(driver, vm, true)) < 0) {
|
||||||
/* To not break the normal domain shutdown process, skip the
|
/* To not break the normal domain shutdown process, skip the
|
||||||
* timestamp log writing if failed on opening log file. */
|
* timestamp log writing if failed on opening log file. */
|
||||||
@ -4233,6 +4245,10 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
vm->def->id = driver->nextvmid++;
|
vm->def->id = driver->nextvmid++;
|
||||||
|
|
||||||
|
if (!driver->nactive && driver->inhibitCallback)
|
||||||
|
driver->inhibitCallback(true, driver->inhibitOpaque);
|
||||||
|
driver->nactive++;
|
||||||
|
|
||||||
if (virFileMakePath(driver->logDir) < 0) {
|
if (virFileMakePath(driver->logDir) < 0) {
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
_("cannot create log directory %s"),
|
_("cannot create log directory %s"),
|
||||||
|
@ -150,7 +150,9 @@ static char *get_transport_from_scheme(char *scheme);
|
|||||||
|
|
||||||
#ifdef WITH_LIBVIRTD
|
#ifdef WITH_LIBVIRTD
|
||||||
static int
|
static int
|
||||||
remoteStartup(bool privileged ATTRIBUTE_UNUSED)
|
remoteStartup(bool privileged ATTRIBUTE_UNUSED,
|
||||||
|
virStateInhibitCallback callback ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
/* Mark that we're inside the daemon so we can avoid
|
/* Mark that we're inside the daemon so we can avoid
|
||||||
* re-entering ourselves
|
* re-entering ourselves
|
||||||
|
@ -101,8 +101,7 @@ struct _virNetServer {
|
|||||||
virNetTLSContextPtr tls;
|
virNetTLSContextPtr tls;
|
||||||
|
|
||||||
unsigned int autoShutdownTimeout;
|
unsigned int autoShutdownTimeout;
|
||||||
virNetServerAutoShutdownFunc autoShutdownFunc;
|
size_t autoShutdownInhibitions;
|
||||||
void *autoShutdownOpaque;
|
|
||||||
|
|
||||||
virNetServerClientPrivNew clientPrivNew;
|
virNetServerClientPrivNew clientPrivNew;
|
||||||
virNetServerClientPrivPreExecRestart clientPrivPreExecRestart;
|
virNetServerClientPrivPreExecRestart clientPrivPreExecRestart;
|
||||||
@ -707,19 +706,33 @@ bool virNetServerIsPrivileged(virNetServerPtr srv)
|
|||||||
|
|
||||||
|
|
||||||
void virNetServerAutoShutdown(virNetServerPtr srv,
|
void virNetServerAutoShutdown(virNetServerPtr srv,
|
||||||
unsigned int timeout,
|
unsigned int timeout)
|
||||||
virNetServerAutoShutdownFunc func,
|
|
||||||
void *opaque)
|
|
||||||
{
|
{
|
||||||
virNetServerLock(srv);
|
virNetServerLock(srv);
|
||||||
|
|
||||||
srv->autoShutdownTimeout = timeout;
|
srv->autoShutdownTimeout = timeout;
|
||||||
srv->autoShutdownFunc = func;
|
|
||||||
srv->autoShutdownOpaque = opaque;
|
|
||||||
|
|
||||||
virNetServerUnlock(srv);
|
virNetServerUnlock(srv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void virNetServerAddShutdownInhibition(virNetServerPtr srv)
|
||||||
|
{
|
||||||
|
virNetServerLock(srv);
|
||||||
|
srv->autoShutdownInhibitions++;
|
||||||
|
virNetServerUnlock(srv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void virNetServerRemoveShutdownInhibition(virNetServerPtr srv)
|
||||||
|
{
|
||||||
|
virNetServerLock(srv);
|
||||||
|
srv->autoShutdownInhibitions--;
|
||||||
|
virNetServerUnlock(srv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static sig_atomic_t sigErrors = 0;
|
static sig_atomic_t sigErrors = 0;
|
||||||
static int sigLastErrno = 0;
|
static int sigLastErrno = 0;
|
||||||
static int sigWrite = -1;
|
static int sigWrite = -1;
|
||||||
@ -932,7 +945,7 @@ static void virNetServerAutoShutdownTimer(int timerid ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
virNetServerLock(srv);
|
virNetServerLock(srv);
|
||||||
|
|
||||||
if (srv->autoShutdownFunc(srv, srv->autoShutdownOpaque)) {
|
if (!srv->autoShutdownInhibitions) {
|
||||||
VIR_DEBUG("Automatic shutdown triggered");
|
VIR_DEBUG("Automatic shutdown triggered");
|
||||||
srv->quit = 1;
|
srv->quit = 1;
|
||||||
}
|
}
|
||||||
|
@ -60,9 +60,10 @@ typedef int (*virNetServerAutoShutdownFunc)(virNetServerPtr srv, void *opaque);
|
|||||||
bool virNetServerIsPrivileged(virNetServerPtr srv);
|
bool virNetServerIsPrivileged(virNetServerPtr srv);
|
||||||
|
|
||||||
void virNetServerAutoShutdown(virNetServerPtr srv,
|
void virNetServerAutoShutdown(virNetServerPtr srv,
|
||||||
unsigned int timeout,
|
unsigned int timeout);
|
||||||
virNetServerAutoShutdownFunc func,
|
|
||||||
void *opaque);
|
void virNetServerAddShutdownInhibition(virNetServerPtr srv);
|
||||||
|
void virNetServerRemoveShutdownInhibition(virNetServerPtr srv);
|
||||||
|
|
||||||
typedef void (*virNetServerSignalFunc)(virNetServerPtr srv, siginfo_t *info, void *opaque);
|
typedef void (*virNetServerSignalFunc)(virNetServerPtr srv, siginfo_t *info, void *opaque);
|
||||||
|
|
||||||
|
@ -1073,7 +1073,9 @@ secretDriverCleanup(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
secretDriverStartup(bool privileged)
|
secretDriverStartup(bool privileged,
|
||||||
|
virStateInhibitCallback callback ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
char *base = NULL;
|
char *base = NULL;
|
||||||
|
|
||||||
@ -1166,7 +1168,6 @@ static virStateDriver stateDriver = {
|
|||||||
.initialize = secretDriverStartup,
|
.initialize = secretDriverStartup,
|
||||||
.cleanup = secretDriverCleanup,
|
.cleanup = secretDriverCleanup,
|
||||||
.reload = secretDriverReload,
|
.reload = secretDriverReload,
|
||||||
.active = NULL /* All persistent state is immediately saved to disk */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -128,7 +128,9 @@ storageDriverAutostart(virStorageDriverStatePtr driver) {
|
|||||||
* Initialization function for the QEmu daemon
|
* Initialization function for the QEmu daemon
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
storageDriverStartup(bool privileged)
|
storageDriverStartup(bool privileged,
|
||||||
|
virStateInhibitCallback callback ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
char *base = NULL;
|
char *base = NULL;
|
||||||
|
|
||||||
|
@ -45,11 +45,14 @@ struct uml_driver {
|
|||||||
virMutex lock;
|
virMutex lock;
|
||||||
|
|
||||||
bool privileged;
|
bool privileged;
|
||||||
|
virStateInhibitCallback inhibitCallback;
|
||||||
|
void *inhibitOpaque;
|
||||||
|
|
||||||
unsigned long umlVersion;
|
unsigned long umlVersion;
|
||||||
int nextvmid;
|
int nextvmid;
|
||||||
|
|
||||||
virDomainObjList domains;
|
virDomainObjList domains;
|
||||||
|
size_t nactive;
|
||||||
|
|
||||||
char *configDir;
|
char *configDir;
|
||||||
char *autostartDir;
|
char *autostartDir;
|
||||||
|
@ -372,6 +372,11 @@ reread:
|
|||||||
}
|
}
|
||||||
|
|
||||||
dom->def->id = driver->nextvmid++;
|
dom->def->id = driver->nextvmid++;
|
||||||
|
|
||||||
|
if (!driver->nactive && driver->inhibitCallback)
|
||||||
|
driver->inhibitCallback(true, driver->inhibitOpaque);
|
||||||
|
driver->nactive++;
|
||||||
|
|
||||||
virDomainObjSetState(dom, VIR_DOMAIN_RUNNING,
|
virDomainObjSetState(dom, VIR_DOMAIN_RUNNING,
|
||||||
VIR_DOMAIN_RUNNING_BOOTED);
|
VIR_DOMAIN_RUNNING_BOOTED);
|
||||||
|
|
||||||
@ -419,7 +424,9 @@ cleanup:
|
|||||||
* Initialization function for the Uml daemon
|
* Initialization function for the Uml daemon
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
umlStartup(bool privileged)
|
umlStartup(bool privileged,
|
||||||
|
virStateInhibitCallback callback,
|
||||||
|
void *opaque)
|
||||||
{
|
{
|
||||||
char *base = NULL;
|
char *base = NULL;
|
||||||
char *userdir = NULL;
|
char *userdir = NULL;
|
||||||
@ -428,6 +435,8 @@ umlStartup(bool privileged)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
uml_driver->privileged = privileged;
|
uml_driver->privileged = privileged;
|
||||||
|
uml_driver->inhibitCallback = callback;
|
||||||
|
uml_driver->inhibitOpaque = opaque;
|
||||||
|
|
||||||
if (virMutexInit(¨_driver->lock) < 0) {
|
if (virMutexInit(¨_driver->lock) < 0) {
|
||||||
VIR_FREE(uml_driver);
|
VIR_FREE(uml_driver);
|
||||||
@ -585,27 +594,6 @@ umlReload(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* umlActive:
|
|
||||||
*
|
|
||||||
* Checks if the Uml daemon is active, i.e. has an active domain or
|
|
||||||
* an active network
|
|
||||||
*
|
|
||||||
* Returns 1 if active, 0 otherwise
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
umlActive(void) {
|
|
||||||
int active = 0;
|
|
||||||
|
|
||||||
if (!uml_driver)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
umlDriverLock(uml_driver);
|
|
||||||
active = virDomainObjListNumOfDomains(¨_driver->domains, 1);
|
|
||||||
umlDriverUnlock(uml_driver);
|
|
||||||
|
|
||||||
return active;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
umlShutdownOneVM(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
|
umlShutdownOneVM(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
|
||||||
@ -1154,6 +1142,10 @@ static void umlShutdownVMDaemon(struct uml_driver *driver,
|
|||||||
vm->def->id = -1;
|
vm->def->id = -1;
|
||||||
vm->newDef = NULL;
|
vm->newDef = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
driver->nactive--;
|
||||||
|
if (!driver->nactive && driver->inhibitCallback)
|
||||||
|
driver->inhibitCallback(false, driver->inhibitOpaque);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2634,7 +2626,6 @@ static virStateDriver umlStateDriver = {
|
|||||||
.initialize = umlStartup,
|
.initialize = umlStartup,
|
||||||
.cleanup = umlShutdown,
|
.cleanup = umlShutdown,
|
||||||
.reload = umlReload,
|
.reload = umlReload,
|
||||||
.active = umlActive,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int umlRegister(void) {
|
int umlRegister(void) {
|
||||||
|
@ -201,7 +201,9 @@ done:
|
|||||||
#ifdef WITH_LIBVIRTD
|
#ifdef WITH_LIBVIRTD
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xenInitialize(bool privileged ATTRIBUTE_UNUSED)
|
xenInitialize(bool privileged ATTRIBUTE_UNUSED,
|
||||||
|
virStateInhibitCallback callback ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
inside_daemon = true;
|
inside_daemon = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user