mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-30 18:50:18 +03:00
hypervisor: move support for auto-shutdown out of QEMU driver
This is a move of the code that currently exists in the QEMU driver, into the common layer that can be used by multiple drivers. The code currently supports performing managed save of all running guests, ignoring any failures. Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
f48fb17d72
commit
991a20a938
@ -713,3 +713,51 @@ virDomainDriverAutoStart(virDomainObjList *domains,
|
||||
|
||||
virDomainObjListForEach(domains, false, virDomainDriverAutoStartOne, &state);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg)
|
||||
{
|
||||
g_autoptr(virConnect) conn = NULL;
|
||||
int numDomains = 0;
|
||||
size_t i;
|
||||
int state;
|
||||
virDomainPtr *domains = NULL;
|
||||
g_autofree unsigned int *flags = NULL;
|
||||
|
||||
if (!(conn = virConnectOpen(cfg->uri)))
|
||||
goto cleanup;
|
||||
|
||||
if ((numDomains = virConnectListAllDomains(conn,
|
||||
&domains,
|
||||
VIR_CONNECT_LIST_DOMAINS_ACTIVE)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
flags = g_new0(unsigned int, numDomains);
|
||||
|
||||
/* First we pause all VMs to make them stop dirtying
|
||||
pages, etc. We remember if any VMs were paused so
|
||||
we can restore that on resume. */
|
||||
for (i = 0; i < numDomains; i++) {
|
||||
flags[i] = VIR_DOMAIN_SAVE_RUNNING;
|
||||
if (virDomainGetState(domains[i], &state, NULL, 0) == 0) {
|
||||
if (state == VIR_DOMAIN_PAUSED)
|
||||
flags[i] = VIR_DOMAIN_SAVE_PAUSED;
|
||||
}
|
||||
virDomainSuspend(domains[i]);
|
||||
}
|
||||
|
||||
/* Then we save the VMs to disk */
|
||||
for (i = 0; i < numDomains; i++)
|
||||
if (virDomainManagedSave(domains[i], flags[i]) < 0)
|
||||
VIR_WARN("Unable to perform managed save of '%s': %s",
|
||||
virDomainGetName(domains[i]),
|
||||
virGetLastErrorMessage());
|
||||
|
||||
cleanup:
|
||||
if (domains) {
|
||||
for (i = 0; i < numDomains; i++)
|
||||
virObjectUnref(domains[i]);
|
||||
VIR_FREE(domains);
|
||||
}
|
||||
}
|
||||
|
@ -90,3 +90,9 @@ typedef struct _virDomainDriverAutoStartConfig {
|
||||
|
||||
void virDomainDriverAutoStart(virDomainObjList *domains,
|
||||
virDomainDriverAutoStartConfig *cfg);
|
||||
|
||||
typedef struct _virDomainDriverAutoShutdownConfig {
|
||||
const char *uri;
|
||||
} virDomainDriverAutoShutdownConfig;
|
||||
|
||||
void virDomainDriverAutoShutdown(virDomainDriverAutoShutdownConfig *cfg);
|
||||
|
@ -1649,6 +1649,7 @@ virDomainCgroupSetupVcpuBW;
|
||||
|
||||
# hypervisor/domain_driver.h
|
||||
virDomainDriverAddIOThreadCheck;
|
||||
virDomainDriverAutoShutdown;
|
||||
virDomainDriverAutoStart;
|
||||
virDomainDriverDelIOThreadCheck;
|
||||
virDomainDriverGenerateMachineName;
|
||||
|
@ -963,51 +963,14 @@ qemuStateReload(void)
|
||||
static int
|
||||
qemuStateStop(void)
|
||||
{
|
||||
int ret = -1;
|
||||
g_autoptr(virConnect) conn = NULL;
|
||||
int numDomains = 0;
|
||||
size_t i;
|
||||
int state;
|
||||
virDomainPtr *domains = NULL;
|
||||
g_autofree unsigned int *flags = NULL;
|
||||
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(qemu_driver);
|
||||
virDomainDriverAutoShutdownConfig ascfg = {
|
||||
.uri = cfg->uri,
|
||||
};
|
||||
|
||||
if (!(conn = virConnectOpen(cfg->uri)))
|
||||
goto cleanup;
|
||||
virDomainDriverAutoShutdown(&ascfg);
|
||||
|
||||
if ((numDomains = virConnectListAllDomains(conn,
|
||||
&domains,
|
||||
VIR_CONNECT_LIST_DOMAINS_ACTIVE)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
flags = g_new0(unsigned int, numDomains);
|
||||
|
||||
/* First we pause all VMs to make them stop dirtying
|
||||
pages, etc. We remember if any VMs were paused so
|
||||
we can restore that on resume. */
|
||||
for (i = 0; i < numDomains; i++) {
|
||||
flags[i] = VIR_DOMAIN_SAVE_RUNNING;
|
||||
if (virDomainGetState(domains[i], &state, NULL, 0) == 0) {
|
||||
if (state == VIR_DOMAIN_PAUSED)
|
||||
flags[i] = VIR_DOMAIN_SAVE_PAUSED;
|
||||
}
|
||||
virDomainSuspend(domains[i]);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
/* Then we save the VMs to disk */
|
||||
for (i = 0; i < numDomains; i++)
|
||||
if (virDomainManagedSave(domains[i], flags[i]) < 0)
|
||||
ret = -1;
|
||||
|
||||
cleanup:
|
||||
if (domains) {
|
||||
for (i = 0; i < numDomains; i++)
|
||||
virObjectUnref(domains[i]);
|
||||
VIR_FREE(domains);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user