[libvirt] [PATCH] start: allow discarding managed save

Daniel Veillard veillard at redhat.com
Tue Aug 30 10:47:41 UTC 2011


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 at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list