aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOt ten Thije <ottenthije@google.com>2010-10-05 17:53:30 +0100
committerOt ten Thije <ottenthije@google.com>2010-10-22 11:18:47 +0100
commit353b3b1135563e2bcaf7797acfa35a2fe2d3a818 (patch)
tree49f495ea08d718709426f03205726bfdc957aa57
parent6133adcd101e17118354e64771c52355dbafb1d7 (diff)
downloadexternal_qemu-353b3b1135563e2bcaf7797acfa35a2fe2d3a818.zip
external_qemu-353b3b1135563e2bcaf7797acfa35a2fe2d3a818.tar.gz
external_qemu-353b3b1135563e2bcaf7797acfa35a2fe2d3a818.tar.bz2
Load state snapshot rather than booting to start emulator.
This patch adds support for an optional file "snapshots.img" in the data directory of an AVD. This file should be an image formatted with the qcow2 file system and will be mounted on -hdb when the emulator starts up. If present, the emulator will attempt to load the snapshot named "default-boot" from this image, rather than going through the full boot procedure. To control the behaviour of this functionality, this patch introduces the following new command line options for the emulator: -snapstorage <file>: override the default location of the snapshot storage file. -no-snapstorage: do not load the snapshots file, even if an explicit path is given. -snapshot <name>: instead of loading "default-boot", load the state snapshot with the given name. -no-snapshot: do not load a snapshot, but force a full boot sequence, even if a snapshots file is mounted. Useful for creating snapshots. Note that this functionality is experimental and will be enabled only if the constant CONFIG_ANDROID_SNAPSHOTS in android/config/config.h is set to "1" before building. It is turned off by default. Change-Id: Iee2e9096a27f3414bacfc271f90ef93a98730c82
-rw-r--r--android/avd/info.c80
-rw-r--r--android/avd/info.h12
-rw-r--r--android/cmdline-options.h6
-rw-r--r--android/config/config.h1
-rw-r--r--android/help.c94
-rw-r--r--android/main.c61
6 files changed, 219 insertions, 35 deletions
diff --git a/android/avd/info.c b/android/avd/info.c
index 992f292..e680585 100644
--- a/android/avd/info.c
+++ b/android/avd/info.c
@@ -10,6 +10,7 @@
** GNU General Public License for more details.
*/
#include "android/avd/info.h"
+#include "android/config/config.h"
#include "android/utils/path.h"
#include "android/utils/bufprint.h"
#include "android/utils/filelock.h"
@@ -681,7 +682,30 @@ EXIT:
return l->pPath[0];
}
+/* Attempts to load an AVD image, but does not kill the process if loading
+ * fails.
+ */
+static void
+imageLoader_loadOptional( ImageLoader *l, AvdImageType img_type,
+ const char *forcedPath )
+{
+ imageLoader_set (l, img_type);
+ imageLoader_load(l, IMAGE_OPTIONAL |
+ IMAGE_IGNORE_IF_LOCKED);
+ /* if the file was not found, ignore it */
+ if (l->pPath[0] && !path_exists(l->pPath[0]))
+ {
+ D("ignoring non-existing %s at %s: %s",
+ l->imageText, l->pPath[0], strerror(errno));
+
+ /* if the user provided the path by hand, warn him. */
+ if (forcedPath != NULL)
+ dwarning("ignoring non-existing %s image", l->imageText);
+
+ imageLoader_setPath(l, NULL);
+ }
+}
/* find the correct path of all image files we're going to need
* and lock the files that need it.
@@ -689,10 +713,13 @@ EXIT:
static int
_getImagePaths(AvdInfo* i, AvdInfoParams* params )
{
- int wipeData = (params->flags & AVDINFO_WIPE_DATA) != 0;
- int wipeCache = (params->flags & AVDINFO_WIPE_CACHE) != 0;
- int noCache = (params->flags & AVDINFO_NO_CACHE) != 0;
- int noSdCard = (params->flags & AVDINFO_NO_SDCARD) != 0;
+ int wipeData = (params->flags & AVDINFO_WIPE_DATA) != 0;
+ int wipeCache = (params->flags & AVDINFO_WIPE_CACHE) != 0;
+ int noCache = (params->flags & AVDINFO_NO_CACHE) != 0;
+ int noSdCard = (params->flags & AVDINFO_NO_SDCARD) != 0;
+#if CONFIG_ANDROID_SNAPSHOTS
+ int noSnapshots = (params->flags & AVDINFO_NO_SNAPSHOTS) != 0;
+#endif
ImageLoader l[1];
@@ -778,24 +805,19 @@ _getImagePaths(AvdInfo* i, AvdInfoParams* params )
* already used, we must ignore it.
*/
if (!noSdCard) {
- imageLoader_set (l, AVD_IMAGE_SDCARD);
- imageLoader_load(l, IMAGE_OPTIONAL |
- IMAGE_IGNORE_IF_LOCKED);
-
- /* if the file was not found, ignore it */
- if (l->pPath[0] && !path_exists(l->pPath[0]))
- {
- D("ignoring non-existing %s at %s: %s",
- l->imageText, l->pPath[0], strerror(errno));
-
- /* if the user provided the SD Card path by hand,
- * warn him. */
- if (params->forcePaths[AVD_IMAGE_SDCARD] != NULL)
- dwarning("ignoring non-existing SD Card image");
+ imageLoader_loadOptional(l, AVD_IMAGE_SDCARD,
+ params->forcePaths[AVD_IMAGE_SDCARD]);
+ }
- imageLoader_setPath(l, NULL);
- }
+#if CONFIG_ANDROID_SNAPSHOTS
+ /* the state snapshot image. Mounting behaviour identical to
+ * SD card.
+ */
+ if (!noSnapshots) {
+ imageLoader_loadOptional(l, AVD_IMAGE_SNAPSHOTS,
+ params->forcePaths[AVD_IMAGE_SNAPSHOTS]);
}
+#endif
return 0;
}
@@ -1146,9 +1168,12 @@ _getBuildConfigIni( AvdInfo* i )
static int
_getBuildImagePaths( AvdInfo* i, AvdInfoParams* params )
{
- int wipeData = (params->flags & AVDINFO_WIPE_DATA) != 0;
- int noCache = (params->flags & AVDINFO_NO_CACHE) != 0;
- int noSdCard = (params->flags & AVDINFO_NO_SDCARD) != 0;
+ int wipeData = (params->flags & AVDINFO_WIPE_DATA) != 0;
+ int noCache = (params->flags & AVDINFO_NO_CACHE) != 0;
+ int noSdCard = (params->flags & AVDINFO_NO_SDCARD) != 0;
+#if CONFIG_ANDROID_SNAPSHOTS
+ int noSnapshots = (params->flags & AVDINFO_NO_SNAPSHOTS) != 0;
+#endif
char temp[PATH_MAX], *p=temp, *end=p+sizeof temp;
char* srcData;
@@ -1263,6 +1288,15 @@ _getBuildImagePaths( AvdInfo* i, AvdInfoParams* params )
imageLoader_load(l, IMAGE_OPTIONAL | IMAGE_IGNORE_IF_LOCKED);
}
+#if CONFIG_ANDROID_SNAPSHOTS
+ /** State snapshots image
+ **/
+ if (!noSnapshots) {
+ imageLoader_set (l, AVD_IMAGE_SNAPSHOTS);
+ imageLoader_load(l, IMAGE_OPTIONAL | IMAGE_IGNORE_IF_LOCKED);
+ }
+#endif
+
return 0;
}
diff --git a/android/avd/info.h b/android/avd/info.h
index 19df807..2b2899f 100644
--- a/android/avd/info.h
+++ b/android/avd/info.h
@@ -14,6 +14,7 @@
#include "android/utils/ini.h"
#include "android/avd/hw-config.h"
+#include "android/config/config.h"
/* An Android Virtual Device (AVD for short) corresponds to a
* directory containing all kernel/disk images for a given virtual
@@ -45,6 +46,12 @@
*
*/
+
+#if CONFIG_ANDROID_SNAPSHOTS
+#define _AVD_IMG_SNAPSHOT _AVD_IMG(SNAPSHOTS,"snapshots.img","snapshots")
+#else
+#define _AVD_IMG_SNAPSHOT
+#endif
/* a macro used to define the list of disk images managed by the
* implementation. This macro will be expanded several times with
* varying definitions of _AVD_IMG
@@ -58,6 +65,7 @@
_AVD_IMG(USERDATA,"userdata-qemu.img", "user data") \
_AVD_IMG(CACHE,"cache.img","cache") \
_AVD_IMG(SDCARD,"sdcard.img","SD Card") \
+ _AVD_IMG_SNAPSHOT \
/* define the enumared values corresponding to each AVD image type
* examples are: AVD_IMAGE_KERNEL, AVD_IMAGE_SYSTEM, etc..
@@ -86,6 +94,10 @@ typedef enum {
AVDINFO_NO_SDCARD = (1 << 3),
/* use to wipe the system image with new initial values */
AVDINFO_WIPE_SYSTEM = (1 << 4),
+#if CONFIG_ANDROID_SNAPSHOTS
+ /* use to ignore ignore state snapshot image (default or provided) */
+ AVDINFO_NO_SNAPSHOTS = (1 << 5),
+#endif
} AvdFlags;
typedef struct {
diff --git a/android/cmdline-options.h b/android/cmdline-options.h
index a311912..a9b02ac 100644
--- a/android/cmdline-options.h
+++ b/android/cmdline-options.h
@@ -76,6 +76,12 @@ CFG_PARAM( cache, "<file>", "cache partition image (default is temporary file
CFG_FLAG ( no_cache, "disable the cache partition" )
CFG_FLAG ( nocache, "same as -no-cache" )
OPT_PARAM( sdcard, "<file>", "SD card image (default <system>/sdcard.img")
+#if CONFIG_ANDROID_SNAPSHOTS
+OPT_PARAM( snapstorage, "<file>", "file that contains all state snapshots (default <datadir>/snapshots.img)")
+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" )
+#endif
OPT_FLAG ( wipe_data, "reset the use data image (copy it from initdata)" )
CFG_PARAM( avd, "<name>", "use a specific android virtual device" )
CFG_PARAM( skindir, "<dir>", "search skins in <dir> (default <system>/skins)" )
diff --git a/android/config/config.h b/android/config/config.h
index e2191e3..ad43dd9 100644
--- a/android/config/config.h
+++ b/android/config/config.h
@@ -13,3 +13,4 @@
#ifndef _WIN32
#define CONFIG_NAND_LIMITS 1
#endif
+#define CONFIG_ANDROID_SNAPSHOTS 0
diff --git a/android/help.c b/android/help.c
index ea419f3..17e7a90 100644
--- a/android/help.c
+++ b/android/help.c
@@ -166,6 +166,9 @@ help_disk_images( stralloc_t* out )
" system-qemu.img an *optional* persistent system image\n"
" cache.img an *optional* cache partition image\n"
" sdcard.img an *optional* SD Card partition image\n\n"
+#if CONFIG_ANDROID_SNAPSHOTS
+ " snapshots.img an *optional* state snapshots image\n\n"
+#endif
" If you use a virtual device, its content directory should store\n"
" all writable images, and read-only ones will be found from the\n"
@@ -181,7 +184,11 @@ help_disk_images( stralloc_t* out )
" can still run the emulator by explicitely providing the paths to\n"
" *all* required disk images through a combination of the following\n"
" options: -sysdir, -datadir, -kernel, -ramdisk, -system, -data, -cache\n"
- " and -sdcard\n\n"
+#if CONFIG_ANDROID_SNAPSHOTS
+ " -sdcard and -snapstorage.\n\n"
+#else
+ " and -sdcard.\n\n"
+#endif
" The actual logic being that the emulator should be able to find all\n"
" images from the options you give it.\n\n"
@@ -190,13 +197,18 @@ help_disk_images( stralloc_t* out )
" Other related options are:\n\n"
- " -init-data Specify an alernative *initial* user data image\n\n"
+ " -init-data Specify an alternative *initial* user data image\n\n"
- " -wipe-data Copy the content of the *initial* user data image\n"
- " (userdata.img) into the writable one (userdata-qemu.img)\n\n"
+ " -wipe-data Copy the content of the *initial* user data image\n"
+" (userdata.img) into the writable one (userdata-qemu.img)\n\n"
- " -no-cache do not use a cache partition, even if one is\n"
- " available.\n\n"
+ " -no-cache do not use a cache partition, even if one is\n"
+ " available.\n\n"
+
+#if CONFIG_ANDROID_SNAPSHOTS
+ " -no-snapstorage do not use a state snapshot image, even if one is\n"
+ " available.\n\n"
+#endif
,
datadir );
}
@@ -620,6 +632,76 @@ help_sdcard(stralloc_t* out)
);
}
+#if CONFIG_ANDROID_SNAPSHOTS
+static void
+help_snapstorage(stralloc_t* out)
+{
+ PRINTF(
+ " Use '-snapstorage <file>' to specify a repository file for snapshots.\n"
+ " All snapshots made during execution will be saved in this file, and only\n"
+ " snapshots in this file can be restored during the emulator run.\n\n"
+
+ " If the option is not specified, it defaults to 'snapshots.img' in the\n"
+ " data directory. If the specified file does not exist, the emulator will\n"
+ " start, but without support for saving or loading state snapshots.\n\n"
+
+ " see '-help-disk-images' for more information about disk image files\n"
+ " see '-help-snapshot' for more information about snapshots\n\n"
+ );
+}
+
+static void
+help_no_snapstorage(stralloc_t* out)
+{
+ PRINTF(
+ " This starts the emulator without mounting a file to store or load state\n"
+ " snapshots, forcing a full boot and disabling state snapshot functionality.\n\n"
+ ""
+ " This command overrides the configuration specified by the parameters\n"
+ " '-snapstorage' and '-snapshot'. A warning will be raised if either\n"
+ " of those parameters was specified anyway.\n\n"
+ );
+ }
+
+static void
+help_snapshot(stralloc_t* out)
+{
+ PRINTF(
+ " Rather than executing a full boot sequence, the Android emulator can\n"
+ " resume execution from an earlier state snapshot (which is usually\n"
+ " significantly faster). When the parameter '-snapshot <name>' is given,\n"
+ " the emulator loads the snapshot of that name from the snapshot image.\n\n"
+
+ " If the option is not specified, it defaults to 'default-boot'. If the\n"
+ " specified snapshot does not exist, the emulator will perform a full boot\n"
+ " sequence instead.\n\n"
+
+ " WARNING: In the process of loading, all contents of the system, userdata\n"
+ " and SD card images will be OVERWRITTEN with the contents they\n"
+ " held when the snapshot was made. Unless saved in a different\n"
+ " snapshot, any changes since will be lost!\n\n"
+
+ " If you want to create a snapshot, connect to the emulator console:\n\n"
+
+ " telnet localhost <port>\n\n"
+
+ " Then execute the command 'avd snapshot save <name>'. See '-help-port' for\n"
+ " information on obtaining <port>.\n\n"
+ );
+}
+
+static void
+help_no_snapshot(stralloc_t* out)
+{
+ PRINTF(
+ " This forces the emulator to perform a full boot sequence, rather than\n"
+ " loading the default snapshot. It overrides the '-snapshot' parameter.\n"
+ " If '-snapshot' was specified anyway, a warning is raised.\n\n"
+ );
+}
+
+#endif
+
static void
help_skindir(stralloc_t* out)
{
diff --git a/android/main.c b/android/main.c
index b88fb5e..a328ad1 100644
--- a/android/main.c
+++ b/android/main.c
@@ -998,6 +998,16 @@ int main(int argc, char **argv)
D("autoconfig: -sdcard %s", opts->sdcard);
}
}
+
+#if CONFIG_ANDROID_SNAPSHOTS
+ if (!opts->snapstorage && opts->datadir) {
+ bufprint(tmp, tmpend, "%s/snapshots.img", opts->datadir);
+ if (path_exists(tmp)) {
+ opts->snapstorage = qemu_strdup(tmp);
+ D("autoconfig: -snapstorage %s", opts->snapstorage);
+ }
+ }
+#endif
}
/* setup the virtual device parameters from our options
@@ -1008,16 +1018,24 @@ int main(int argc, char **argv)
if (opts->wipe_data) {
android_avdParams->flags |= AVDINFO_WIPE_DATA | AVDINFO_WIPE_CACHE;
}
+#if CONFIG_ANDROID_SNAPSHOTS
+ if (opts->no_snapstorage) {
+ android_avdParams->flags |= AVDINFO_NO_SNAPSHOTS;
+ }
+#endif
/* if certain options are set, we can force the path of
* certain kernel/disk image files
*/
- _forceAvdImagePath(AVD_IMAGE_KERNEL, opts->kernel, "kernel", 1);
- _forceAvdImagePath(AVD_IMAGE_INITSYSTEM, opts->system, "system", 1);
- _forceAvdImagePath(AVD_IMAGE_RAMDISK, opts->ramdisk,"ramdisk", 1);
- _forceAvdImagePath(AVD_IMAGE_USERDATA, opts->data, "user data", 0);
- _forceAvdImagePath(AVD_IMAGE_CACHE, opts->cache, "cache", 0);
- _forceAvdImagePath(AVD_IMAGE_SDCARD, opts->sdcard, "SD Card", 0);
+ _forceAvdImagePath(AVD_IMAGE_KERNEL, opts->kernel, "kernel", 1);
+ _forceAvdImagePath(AVD_IMAGE_INITSYSTEM, opts->system, "system", 1);
+ _forceAvdImagePath(AVD_IMAGE_RAMDISK, opts->ramdisk, "ramdisk", 1);
+ _forceAvdImagePath(AVD_IMAGE_USERDATA, opts->data, "user data", 0);
+ _forceAvdImagePath(AVD_IMAGE_CACHE, opts->cache, "cache", 0);
+ _forceAvdImagePath(AVD_IMAGE_SDCARD, opts->sdcard, "SD Card", 0);
+#if CONFIG_ANDROID_SNAPSHOTS
+ _forceAvdImagePath(AVD_IMAGE_SNAPSHOTS, opts->snapstorage, "snapshots", 0);
+#endif
/* we don't accept -skindir without -skin now
* to simplify the autoconfig stuff with virtual devices
@@ -1376,6 +1394,37 @@ int main(int argc, char **argv)
}
}
+#if CONFIG_ANDROID_SNAPSHOTS
+ if (!opts->no_snapstorage) {
+ opts->snapstorage = (char*) avdInfo_getImageFile(avd, AVD_IMAGE_SNAPSHOTS);
+ if(opts->snapstorage) {
+ if (path_exists(opts->snapstorage)) {
+ args[n++] = "-hdb";
+ args[n++] = opts->snapstorage;
+ } else {
+ D("no image at '%s', state snapshots disabled", opts->snapstorage);
+ }
+ }
+
+ if (!opts->no_snapshot) {
+ 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";
+ }
+ } else if (opts->snapshot) {
+ dwarning("option '-no-snapshot' overrides '-snapshot', continuing with boot sequence");
+ }
+ } else if (opts->snapshot || opts->snapstorage) {
+ dwarning("option '-no-snapstorage' overrides '-snapshot' and '-snapstorage', "
+ "continuing with full boot, state snapshots are disabled");
+ } else if (opts->no_snapshot) {
+ D("ignoring redundant option '-no-snapshot' implied by '-no-snapstorage'");
+ }
+#endif
+
if (!opts->logcat || opts->logcat[0] == 0) {
opts->logcat = getenv("ANDROID_LOG_TAGS");
if (opts->logcat && opts->logcat[0] == 0)