On Sat, Aug 27, 2011 at 05:21:11PM -0600, Eric Blake wrote: > There have been several instances of people having problems with > a broken managed save file causing 'virsh start' to fail, and not > being 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. > --- > include/libvirt/libvirt.h.in | 1 + > src/libvirt.c | 3 ++ > src/qemu/qemu_driver.c | 50 +++++++++++++++++++++++++---------------- > tools/virsh.c | 7 +++++- > tools/virsh.pod | 5 ++- > 5 files changed, 43 insertions(+), 23 deletions(-) > > diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in > index 53a2f7d..c51a5b9 100644 > --- a/include/libvirt/libvirt.h.in > +++ b/include/libvirt/libvirt.h.in > @@ -236,6 +236,7 @@ typedef enum { > 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_BYPASS_CACHE = 1 << 2, /* Avoid file system cache pollution */ > + VIR_DOMAIN_START_FORCE_BOOT = 1 << 3, /* Boot, discarding any managed save */ > } virDomainCreateFlags; > > > diff --git a/src/libvirt.c b/src/libvirt.c > index 65a099b..80c8b7c 100644 > --- a/src/libvirt.c > +++ b/src/libvirt.c > @@ -7081,6 +7081,9 @@ error: > * 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. > * > + * 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 > */ > int > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index f21122d..5033998 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -120,9 +120,7 @@ static int qemudShutdown(void); > static int qemuDomainObjStart(virConnectPtr conn, > struct qemud_driver *driver, > virDomainObjPtr vm, > - bool start_paused, > - bool autodestroy, > - bool bypass_cache); > + unsigned int flags); > > static int qemudDomainGetMaxVcpus(virDomainPtr dom); > > @@ -135,11 +133,16 @@ struct qemuAutostartData { > }; > > 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; > struct qemuAutostartData *data = opaque; > virErrorPtr err; > + int flags = 0; > + > + if (data->driver->autoStartBypassCache) > + flags |= VIR_DOMAIN_START_BYPASS_CACHE; > > virDomainObjLock(vm); > virResetLastError(); > @@ -152,9 +155,7 @@ qemuAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaq > } else { > if (vm->autostart && > !virDomainObjIsActive(vm) && > - qemuDomainObjStart(data->conn, data->driver, vm, > - false, false, > - data->driver->autoStartBypassCache) < 0) { > + qemuDomainObjStart(data->conn, data->driver, vm, flags) < 0) { > err = virGetLastError(); > VIR_ERROR(_("Failed to autostart VM '%s': %s"), > vm->def->name, > @@ -4441,12 +4442,14 @@ static int > qemuDomainObjStart(virConnectPtr conn, > struct qemud_driver *driver, > virDomainObjPtr vm, > - bool start_paused, > - bool autodestroy, > - bool bypass_cache) > + unsigned int flags) > { > int ret = -1; > 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 > @@ -4458,13 +4461,22 @@ qemuDomainObjStart(virConnectPtr conn, > goto cleanup; > > if (virFileExists(managed_save)) { > - ret = qemuDomainObjRestore(conn, driver, vm, managed_save, > - bypass_cache); > + if (force_boot) { > + 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)) > - VIR_WARN("Failed to remove the managed state %s", managed_save); > + if ((ret == 0) && (unlink(managed_save) < 0)) > + VIR_WARN("Failed to remove the managed state %s", managed_save); > > - goto cleanup; > + goto cleanup; > + } > } > > ret = qemuProcessStart(conn, driver, vm, NULL, start_paused, > @@ -4493,7 +4505,8 @@ qemuDomainStartWithFlags(virDomainPtr dom, unsigned int flags) > > virCheckFlags(VIR_DOMAIN_START_PAUSED | > VIR_DOMAIN_START_AUTODESTROY | > - VIR_DOMAIN_START_BYPASS_CACHE, -1); > + VIR_DOMAIN_START_BYPASS_CACHE | > + VIR_DOMAIN_START_FORCE_BOOT, -1); > > qemuDriverLock(driver); > vm = virDomainFindByUUID(&driver->domains, dom->uuid); > @@ -4515,10 +4528,7 @@ qemuDomainStartWithFlags(virDomainPtr dom, unsigned int flags) > goto endjob; > } > > - if (qemuDomainObjStart(dom->conn, driver, vm, > - (flags & VIR_DOMAIN_START_PAUSED) != 0, > - (flags & VIR_DOMAIN_START_AUTODESTROY) != 0, > - (flags & VIR_DOMAIN_START_BYPASS_CACHE) != 0) < 0) > + if (qemuDomainObjStart(dom->conn, driver, vm, flags) < 0) > goto endjob; > > ret = 0; > diff --git a/tools/virsh.c b/tools/virsh.c > index 15b9bdd..49034ae 100644 > --- a/tools/virsh.c > +++ b/tools/virsh.c > @@ -1537,9 +1537,12 @@ static const vshCmdOptDef opts_start[] = { > {"console", VSH_OT_BOOL, 0, N_("attach to console after creation")}, > #endif > {"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, > 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} > }; > > @@ -1572,6 +1575,8 @@ cmdStart(vshControl *ctl, const vshCmd *cmd) > flags |= VIR_DOMAIN_START_AUTODESTROY; > if (vshCommandOptBool(cmd, "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. */ > if ((flags ? virDomainCreateWithFlags(dom, flags) > diff --git a/tools/virsh.pod b/tools/virsh.pod > index 81d7a1e..2cd0f73 100644 > --- a/tools/virsh.pod > +++ b/tools/virsh.pod > @@ -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. > > =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 > 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 > exits. If I<--bypass-cache> is specified, and managedsave state exists, > 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> ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list