diff options
-rw-r--r-- | android/avd/info.c | 80 | ||||
-rw-r--r-- | android/avd/info.h | 12 | ||||
-rw-r--r-- | android/cmdline-options.h | 6 | ||||
-rw-r--r-- | android/config/config.h | 1 | ||||
-rw-r--r-- | android/help.c | 94 | ||||
-rw-r--r-- | android/main.c | 61 |
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) |