Augment the auto-loadvm behaviour with corresponding auto-savevm-on-exit behaviour.

Autosave fires when loadvm would have been tried - whether it succeeded or not - in
order to bootstrap from an empty snapshot file.

 - New autosave behaviour inhibited with -no_snapshot_save flag.
 - Underlying behaviour implemented with a new qemu option -savevm_on_exit

Change-Id: If64d89f004565ecbb431bc7e96ecc37e27876d67
diff --git a/android/cmdline-options.h b/android/cmdline-options.h
index 1ae3121..3aaa478 100644
--- a/android/cmdline-options.h
+++ b/android/cmdline-options.h
@@ -81,6 +81,7 @@
 OPT_FLAG ( no_snapstorage, "do not mount a snapshot storage file (this disables all snapshot functionality)" )
 OPT_PARAM( snapshot,       "<name>", "immediately load state snapshot rather than doing a full boot (default 'default-boot')" )
 OPT_FLAG ( no_snapshot,    "do not start from snapshot, but perform a full boot sequence" )
+OPT_FLAG ( no_snapshot_save, "do not preserve snapshot, if restore was attempted" )
 OPT_FLAG ( snapshot_list,  "show a list of available snapshots" )
 #endif
 OPT_FLAG ( wipe_data, "reset the use data image (copy it from initdata)" )
diff --git a/android/help.c b/android/help.c
index 2103b00..348e2e6 100644
--- a/android/help.c
+++ b/android/help.c
@@ -701,6 +701,15 @@
 }
 
 static void
+help_no_snapshot_save(stralloc_t*  out)
+{
+    PRINTF(
+    "  Prevents the emulator from saving the AVD's state to the snapshot\n"
+    "  storage on exit, meaning that all changes will be lost.\n\n"
+    );
+}
+
+static void
 help_snapshot_list(stralloc_t*  out)
 {
     PRINTF(
diff --git a/android/main-ui.c b/android/main-ui.c
index e1ad576..9366efd 100644
--- a/android/main-ui.c
+++ b/android/main-ui.c
@@ -1518,12 +1518,13 @@
         }
 
         if (!opts->no_snapshot) {
+            char* snapshot_name =
+                opts->snapshot ? opts->snapshot : "default-boot";
             args[n++] = "-loadvm";
-            if (opts->snapshot) {
-                args[n++] = opts->snapshot;
-            } else {
-                // name of state snapshot to load if not specified by user
-                args[n++] = "default-boot";
+            args[n++] = snapshot_name;
+            if (!opts->no_snapshot_save) {
+              args[n++] = "-savevm-on-exit";
+              args[n++] = snapshot_name;
             }
         } else if (opts->snapshot) {
             dwarning("option '-no-snapshot' overrides '-snapshot', continuing with boot sequence");
diff --git a/android/main.c b/android/main.c
index c1a4a9f..677980b 100644
--- a/android/main.c
+++ b/android/main.c
@@ -1410,12 +1410,13 @@
         }
 
         if (!opts->no_snapshot) {
+            char* snapshot_name =
+                opts->snapshot ? opts->snapshot : "default-boot";
             args[n++] = "-loadvm";
-            if (opts->snapshot) {
-                args[n++] = opts->snapshot;
-            } else {
-                // name of state snapshot to load if not specified by user
-                args[n++] = "default-boot";
+            args[n++] = snapshot_name;
+            if (!opts->no_snapshot_save) {
+              args[n++] = "-savevm-on-exit";
+              args[n++] = snapshot_name;
             }
         } else if (opts->snapshot) {
             dwarning("option '-no-snapshot' overrides '-snapshot', continuing with boot sequence");
diff --git a/qemu-options.hx b/qemu-options.hx
index 44443bc..aee7b6b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1600,6 +1600,14 @@
 
 #if 1 /* ANDROID */
 
+DEF("savevm-on-exit", HAS_ARG, QEMU_OPTION_savevm_on_exit, \
+    "savevm-on-exit [tag|id]\n" \
+    "                save state automatically on exit\n")
+STEXI
+@item -savevm-on-exit @var{file}
+Save state automatically on exit (as @code{savevm} in monitor)
+ETEXI
+
 DEF("mic", HAS_ARG, QEMU_OPTION_mic, \
     "-mic <file>     read audio input from wav file\n")
 
diff --git a/vl-android.c b/vl-android.c
index 1f65c3b..6d99d6d 100644
--- a/vl-android.c
+++ b/vl-android.c
@@ -394,6 +394,10 @@
 
 extern void  dprint( const char* format, ... );
 
+#if CONFIG_ANDROID_SNAPSHOTS
+const char* savevm_on_exit = NULL;
+#endif
+
 #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
 /* Reports the core initialization failure to the error stdout and to the UI
@@ -3234,8 +3238,14 @@
             if (no_shutdown) {
                 vm_stop(0);
                 no_shutdown = 0;
-            } else
+            } else {
+#if CONFIG_ANDROID_SNAPSHOTS
+                if (savevm_on_exit != NULL) {
+                  do_savevm(cur_mon, savevm_on_exit);
+                }
+#endif
                 break;
+            }
         }
         if (qemu_reset_requested()) {
             pause_all_vcpus();
@@ -4292,9 +4302,14 @@
                 parallel_devices[parallel_device_index] = optarg;
                 parallel_device_index++;
                 break;
-	    case QEMU_OPTION_loadvm:
-		loadvm = optarg;
-		break;
+            case QEMU_OPTION_loadvm:
+                loadvm = optarg;
+                break;
+#if CONFIG_ANDROID_SNAPSHOTS
+            case QEMU_OPTION_savevm_on_exit:
+                savevm_on_exit = optarg;
+                break;
+#endif
             case QEMU_OPTION_full_screen:
                 full_screen = 1;
                 break;