aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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)