mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 19:32:19 +00:00
start: allow discarding managed save
There have been several instances of people having problems with a broken managed save file, and not aware that they could use 'virsh managedsave-remove dom' to fix things. Making it possible to do this as part of starting a domain makes the same functionality easier to find, and one less API call. * include/libvirt/libvirt.h.in (VIR_DOMAIN_START_FORCE_BOOT): New flag. * src/libvirt.c (virDomainCreateWithFlags): Document it. * src/qemu/qemu_driver.c (qemuDomainObjStart): Alter signature. (qemuAutostartDomain, qemuDomainStartWithFlags): Update callers. * tools/virsh.c (cmdStart): Expose it in virsh. * tools/virsh.pod (start): Document it.
This commit is contained in:
parent
71a0beaf3a
commit
27c8526053
@ -236,6 +236,7 @@ typedef enum {
|
|||||||
VIR_DOMAIN_START_PAUSED = 1 << 0, /* Launch guest in paused state */
|
VIR_DOMAIN_START_PAUSED = 1 << 0, /* Launch guest in paused state */
|
||||||
VIR_DOMAIN_START_AUTODESTROY = 1 << 1, /* Automatically kill guest when virConnectPtr is closed */
|
VIR_DOMAIN_START_AUTODESTROY = 1 << 1, /* Automatically kill guest when virConnectPtr is closed */
|
||||||
VIR_DOMAIN_START_BYPASS_CACHE = 1 << 2, /* Avoid file system cache pollution */
|
VIR_DOMAIN_START_BYPASS_CACHE = 1 << 2, /* Avoid file system cache pollution */
|
||||||
|
VIR_DOMAIN_START_FORCE_BOOT = 1 << 3, /* Boot, discarding any managed save */
|
||||||
} virDomainCreateFlags;
|
} virDomainCreateFlags;
|
||||||
|
|
||||||
|
|
||||||
|
@ -7081,6 +7081,9 @@ error:
|
|||||||
* the file, or fail if it cannot do so for the given system; this can allow
|
* the file, or fail if it cannot do so for the given system; this can allow
|
||||||
* less pressure on file system cache, but also risks slowing loads from NFS.
|
* less pressure on file system cache, but also risks slowing loads from NFS.
|
||||||
*
|
*
|
||||||
|
* If the VIR_DOMAIN_START_FORCE_BOOT flag is set, then any managed save
|
||||||
|
* file for this domain is discarded, and the domain boots from scratch.
|
||||||
|
*
|
||||||
* Returns 0 in case of success, -1 in case of error
|
* Returns 0 in case of success, -1 in case of error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
@ -120,9 +120,7 @@ static int qemudShutdown(void);
|
|||||||
static int qemuDomainObjStart(virConnectPtr conn,
|
static int qemuDomainObjStart(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
bool start_paused,
|
unsigned int flags);
|
||||||
bool autodestroy,
|
|
||||||
bool bypass_cache);
|
|
||||||
|
|
||||||
static int qemudDomainGetMaxVcpus(virDomainPtr dom);
|
static int qemudDomainGetMaxVcpus(virDomainPtr dom);
|
||||||
|
|
||||||
@ -135,11 +133,16 @@ struct qemuAutostartData {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qemuAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
|
qemuAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque)
|
||||||
{
|
{
|
||||||
virDomainObjPtr vm = payload;
|
virDomainObjPtr vm = payload;
|
||||||
struct qemuAutostartData *data = opaque;
|
struct qemuAutostartData *data = opaque;
|
||||||
virErrorPtr err;
|
virErrorPtr err;
|
||||||
|
int flags = 0;
|
||||||
|
|
||||||
|
if (data->driver->autoStartBypassCache)
|
||||||
|
flags |= VIR_DOMAIN_START_BYPASS_CACHE;
|
||||||
|
|
||||||
virDomainObjLock(vm);
|
virDomainObjLock(vm);
|
||||||
virResetLastError();
|
virResetLastError();
|
||||||
@ -152,9 +155,7 @@ qemuAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaq
|
|||||||
} else {
|
} else {
|
||||||
if (vm->autostart &&
|
if (vm->autostart &&
|
||||||
!virDomainObjIsActive(vm) &&
|
!virDomainObjIsActive(vm) &&
|
||||||
qemuDomainObjStart(data->conn, data->driver, vm,
|
qemuDomainObjStart(data->conn, data->driver, vm, flags) < 0) {
|
||||||
false, false,
|
|
||||||
data->driver->autoStartBypassCache) < 0) {
|
|
||||||
err = virGetLastError();
|
err = virGetLastError();
|
||||||
VIR_ERROR(_("Failed to autostart VM '%s': %s"),
|
VIR_ERROR(_("Failed to autostart VM '%s': %s"),
|
||||||
vm->def->name,
|
vm->def->name,
|
||||||
@ -4441,12 +4442,14 @@ static int
|
|||||||
qemuDomainObjStart(virConnectPtr conn,
|
qemuDomainObjStart(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
bool start_paused,
|
unsigned int flags)
|
||||||
bool autodestroy,
|
|
||||||
bool bypass_cache)
|
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
char *managed_save;
|
char *managed_save;
|
||||||
|
bool start_paused = (flags & VIR_DOMAIN_START_PAUSED) != 0;
|
||||||
|
bool autodestroy = (flags & VIR_DOMAIN_START_AUTODESTROY) != 0;
|
||||||
|
bool bypass_cache = (flags & VIR_DOMAIN_START_BYPASS_CACHE) != 0;
|
||||||
|
bool force_boot = (flags & VIR_DOMAIN_START_FORCE_BOOT) != 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is a managed saved state restore it instead of starting
|
* If there is a managed saved state restore it instead of starting
|
||||||
@ -4458,13 +4461,22 @@ qemuDomainObjStart(virConnectPtr conn,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virFileExists(managed_save)) {
|
if (virFileExists(managed_save)) {
|
||||||
ret = qemuDomainObjRestore(conn, driver, vm, managed_save,
|
if (force_boot) {
|
||||||
bypass_cache);
|
if (unlink(managed_save) < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("cannot remove managed save file %s"),
|
||||||
|
managed_save);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = qemuDomainObjRestore(conn, driver, vm, managed_save,
|
||||||
|
bypass_cache);
|
||||||
|
|
||||||
if ((ret == 0) && (unlink(managed_save) < 0))
|
if ((ret == 0) && (unlink(managed_save) < 0))
|
||||||
VIR_WARN("Failed to remove the managed state %s", managed_save);
|
VIR_WARN("Failed to remove the managed state %s", managed_save);
|
||||||
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = qemuProcessStart(conn, driver, vm, NULL, start_paused,
|
ret = qemuProcessStart(conn, driver, vm, NULL, start_paused,
|
||||||
@ -4493,7 +4505,8 @@ qemuDomainStartWithFlags(virDomainPtr dom, unsigned int flags)
|
|||||||
|
|
||||||
virCheckFlags(VIR_DOMAIN_START_PAUSED |
|
virCheckFlags(VIR_DOMAIN_START_PAUSED |
|
||||||
VIR_DOMAIN_START_AUTODESTROY |
|
VIR_DOMAIN_START_AUTODESTROY |
|
||||||
VIR_DOMAIN_START_BYPASS_CACHE, -1);
|
VIR_DOMAIN_START_BYPASS_CACHE |
|
||||||
|
VIR_DOMAIN_START_FORCE_BOOT, -1);
|
||||||
|
|
||||||
qemuDriverLock(driver);
|
qemuDriverLock(driver);
|
||||||
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
||||||
@ -4515,10 +4528,7 @@ qemuDomainStartWithFlags(virDomainPtr dom, unsigned int flags)
|
|||||||
goto endjob;
|
goto endjob;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemuDomainObjStart(dom->conn, driver, vm,
|
if (qemuDomainObjStart(dom->conn, driver, vm, flags) < 0)
|
||||||
(flags & VIR_DOMAIN_START_PAUSED) != 0,
|
|
||||||
(flags & VIR_DOMAIN_START_AUTODESTROY) != 0,
|
|
||||||
(flags & VIR_DOMAIN_START_BYPASS_CACHE) != 0) < 0)
|
|
||||||
goto endjob;
|
goto endjob;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -1537,9 +1537,12 @@ static const vshCmdOptDef opts_start[] = {
|
|||||||
{"console", VSH_OT_BOOL, 0, N_("attach to console after creation")},
|
{"console", VSH_OT_BOOL, 0, N_("attach to console after creation")},
|
||||||
#endif
|
#endif
|
||||||
{"paused", VSH_OT_BOOL, 0, N_("leave the guest paused after creation")},
|
{"paused", VSH_OT_BOOL, 0, N_("leave the guest paused after creation")},
|
||||||
{"autodestroy", VSH_OT_BOOL, 0, N_("automatically destroy the guest when virsh disconnects")},
|
{"autodestroy", VSH_OT_BOOL, 0,
|
||||||
|
N_("automatically destroy the guest when virsh disconnects")},
|
||||||
{"bypass-cache", VSH_OT_BOOL, 0,
|
{"bypass-cache", VSH_OT_BOOL, 0,
|
||||||
N_("avoid file system cache when loading")},
|
N_("avoid file system cache when loading")},
|
||||||
|
{"force-boot", VSH_OT_BOOL, 0,
|
||||||
|
N_("force fresh boot by discarding any managed save")},
|
||||||
{NULL, 0, 0, NULL}
|
{NULL, 0, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1572,6 +1575,8 @@ cmdStart(vshControl *ctl, const vshCmd *cmd)
|
|||||||
flags |= VIR_DOMAIN_START_AUTODESTROY;
|
flags |= VIR_DOMAIN_START_AUTODESTROY;
|
||||||
if (vshCommandOptBool(cmd, "bypass-cache"))
|
if (vshCommandOptBool(cmd, "bypass-cache"))
|
||||||
flags |= VIR_DOMAIN_START_BYPASS_CACHE;
|
flags |= VIR_DOMAIN_START_BYPASS_CACHE;
|
||||||
|
if (vshCommandOptBool(cmd, "force-boot"))
|
||||||
|
flags |= VIR_DOMAIN_START_FORCE_BOOT;
|
||||||
|
|
||||||
/* Prefer older API unless we have to pass a flag. */
|
/* Prefer older API unless we have to pass a flag. */
|
||||||
if ((flags ? virDomainCreateWithFlags(dom, flags)
|
if ((flags ? virDomainCreateWithFlags(dom, flags)
|
||||||
|
@ -890,7 +890,7 @@ The exact behavior of a domain when it shuts down is set by the
|
|||||||
I<on_shutdown> parameter in the domain's XML definition.
|
I<on_shutdown> parameter in the domain's XML definition.
|
||||||
|
|
||||||
=item B<start> I<domain-name> [I<--console>] [I<--paused>] [I<--autodestroy>]
|
=item B<start> I<domain-name> [I<--console>] [I<--paused>] [I<--autodestroy>]
|
||||||
[I<--bypass-cache>]
|
[I<--bypass-cache>] [I<--force-boot>]
|
||||||
|
|
||||||
Start a (previously defined) inactive domain, either from the last
|
Start a (previously defined) inactive domain, either from the last
|
||||||
B<managedsave> state, or via a fresh boot if no managedsave state is
|
B<managedsave> state, or via a fresh boot if no managedsave state is
|
||||||
@ -901,7 +901,8 @@ If I<--autodestroy> is requested, then the guest will be automatically
|
|||||||
destroyed when virsh closes its connection to libvirt, or otherwise
|
destroyed when virsh closes its connection to libvirt, or otherwise
|
||||||
exits. If I<--bypass-cache> is specified, and managedsave state exists,
|
exits. If I<--bypass-cache> is specified, and managedsave state exists,
|
||||||
the restore will avoid the file system cache, although this may slow
|
the restore will avoid the file system cache, although this may slow
|
||||||
down the operation.
|
down the operation. If I<--force-boot> is specified, then any
|
||||||
|
managedsave state is discarded and a fresh boot occurs.
|
||||||
|
|
||||||
=item B<suspend> I<domain-id>
|
=item B<suspend> I<domain-id>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user