]> xenbits.xensource.com Git - libvirt.git/commitdiff
start: allow discarding managed save
authorEric Blake <eblake@redhat.com>
Sat, 27 Aug 2011 23:07:18 +0000 (17:07 -0600)
committerEric Blake <eblake@redhat.com>
Tue, 30 Aug 2011 15:26:47 +0000 (09:26 -0600)
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.

include/libvirt/libvirt.h.in
src/libvirt.c
src/qemu/qemu_driver.c
tools/virsh.c
tools/virsh.pod

index 53a2f7d6f2d46415c39f51ed51a663c40bab1092..c51a5b9ddd6f4e754e19e1bb2dec0cb4e8b60833 100644 (file)
@@ -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;
 
 
index 65a099b36c9f0fbcb3dd100eb5c6a826971cc3a7..80c8b7cd017151aaa6ccb89910a3332532a8b446 100644 (file)
@@ -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
index f21122d930dc8ae8b89d99eebbffac2930b4e069..5033998703773f5598554847b6120b8cc466bbc1 100644 (file)
@@ -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;
index 15b9bdd4f0f8a915188f53e5ba98e19673840fd4..49034aec26aabc69aee3205166447fec5b6ad367 100644 (file)
@@ -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)
index 81d7a1e35ffe45ac315db85c3dddcf8bfc5c373b..2cd0f738c3aae6dceda7c2093fe0d2433a53d6e7 100644 (file)
@@ -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>