Merge "Fix: create missing partition images on demand."
diff --git a/android/main.c b/android/main.c
index 363c923..9e2a7fb 100644
--- a/android/main.c
+++ b/android/main.c
@@ -78,6 +78,8 @@
extern int qemu_milli_needed;
+extern bool android_op_wipe_data;
+
/* the default device DPI if none is specified by the skin
*/
#define DEFAULT_DEVICE_DPI 165
@@ -706,6 +708,7 @@
} else {
hw->disk_dataPartition_initPath = NULL;
}
+ android_op_wipe_data = opts->wipe_data;
uint64_t defaultBytes =
hw->disk_dataPartition_size == 0 ?
diff --git a/vl-android.c b/vl-android.c
index e8a3779..2d4751a 100644
--- a/vl-android.c
+++ b/vl-android.c
@@ -395,6 +395,8 @@
/* -android-avdname option value. */
char* android_op_avd_name = "unknown";
+bool android_op_wipe_data = false;
+
extern int android_display_width;
extern int android_display_height;
extern int android_display_bpp;
@@ -1868,6 +1870,24 @@
}
+// List of value describing how to handle partition images in
+// android_nand_add_image() below, when no initiali partition image
+// file is provided.
+//
+// MUST_EXIST means that the partition image must exist, otherwise
+// dump an error message and exit.
+//
+// CREATE_IF_NEEDED means that if the partition image doesn't exist, an
+// empty partition file should be created on demand.
+//
+// MUST_WIPE means that the partition image should be wiped cleaned,
+// even if it exists. This is useful to implement the -wipe-data option.
+typedef enum {
+ ANDROID_PARTITION_OPEN_MODE_MUST_EXIST,
+ ANDROID_PARTITION_OPEN_MODE_CREATE_IF_NEEDED,
+ ANDROID_PARTITION_OPEN_MODE_MUST_WIPE,
+} AndroidPartitionOpenMode;
+
// Add a NAND partition image to the hardware configuration.
// |part_name| is a string indicating the type of partition, i.e. "system",
// "userdata" or "cache".
@@ -1908,6 +1928,7 @@
//
void android_nand_add_image(const char* part_name,
AndroidPartitionType part_type,
+ AndroidPartitionOpenMode part_mode,
uint64_t part_size,
const char* part_file,
const char* part_init_file)
@@ -1940,51 +1961,52 @@
// Verify partition type, or probe it if needed.
{
const char* image_file = NULL;
- if (part_init_file && path_exists(part_init_file)) {
- image_file = part_init_file;
- } else if (part_file && path_exists(part_file)) {
+ if (part_file && path_exists(part_file)) {
image_file = part_file;
+ } else if (part_init_file) {
+ image_file = part_init_file;
+ } else if (part_type == ANDROID_PARTITION_TYPE_UNKNOWN) {
+ PANIC("Cannot determine type of %s partition: no image files!",
+ part_name);
}
if (part_type == ANDROID_PARTITION_TYPE_UNKNOWN) {
- if (!image_file) {
- PANIC("Cannot determine type of %s partition: no image files!",
- part_name);
- }
VERBOSE_PRINT(init, "Probing %s image file for partition type: %s",
part_name, image_file);
part_type = androidPartitionType_probeFile(image_file);
-
- VERBOSE_PRINT(init, "Found %s image format: %s",
- part_name, androidPartitionType_toString(part_type));
} else {
- if (!image_file) {
- PANIC("Cannot find any %s file!", part_name);
- }
+ // Probe the current image file to check that it is of the
+ // right partition format.
+ if (image_file) {
+ AndroidPartitionType image_type =
+ androidPartitionType_probeFile(image_file);
+ if (image_type == ANDROID_PARTITION_TYPE_UNKNOWN) {
+ PANIC("Cannot determine %s partition type of: %s",
+ part_name,
+ image_file);
+ }
- AndroidPartitionType image_type =
- androidPartitionType_probeFile(image_file);
- if (image_type == ANDROID_PARTITION_TYPE_UNKNOWN) {
- PANIC("Cannot determine %s partition type of: %s", part_name,
- image_file);
- }
-
- if (image_type != part_type) {
- PANIC("Invalid %s partition image type: %s (expected %s)",
- part_name,
- androidPartitionType_toString(image_type),
- androidPartitionType_toString(part_type));
+ if (image_type != part_type) {
+ PANIC("Invalid %s partition image type: %s (expected %s)",
+ part_name,
+ androidPartitionType_toString(image_type),
+ androidPartitionType_toString(part_type));
+ }
}
}
}
+ VERBOSE_PRINT(init, "%s partition format: %s", part_name,
+ androidPartitionType_toString(part_type));
+
snprintf(tmp, sizeof tmp, "%s,size=0x%" PRIx64, part_name, part_size);
bool need_temp_partition = true;
- bool need_make_empty = false;
+ bool need_make_empty =
+ (part_mode == ANDROID_PARTITION_OPEN_MODE_MUST_WIPE);
- if (part_file && *part_file) {
+ if (part_file) {
if (filelock_create(part_file) == NULL) {
fprintf(stderr,
"WARNING: %s image already in use, changes will not persist!\n",
@@ -1992,7 +2014,18 @@
} else {
need_temp_partition = false;
- if (!path_exists(part_file) && !part_init_file) {
+ // If the partition image is missing, create it.
+ if (!path_exists(part_file)) {
+ if (part_mode == ANDROID_PARTITION_OPEN_MODE_MUST_EXIST) {
+ PANIC("Missing %s partition image: %s", part_name,
+ part_file);
+ }
+ if (path_empty_file(part_file) < 0) {
+ PANIC("Cannot create %s image file at %s: %s",
+ part_name,
+ part_file,
+ strerror(errno));
+ }
need_make_empty = true;
}
}
@@ -2018,7 +2051,13 @@
pstrcat(tmp, sizeof tmp, part_file);
// Do we need to make the partition image empty?
+ // Do not do it if there is an initial file though since it will
+ // get copied directly by the NAND code into the image.
if (need_make_empty && !part_init_file) {
+ VERBOSE_PRINT(init,
+ "Creating empty %s partition image at: %s",
+ part_name,
+ part_file);
int ret = androidPartitionType_makeEmptyFile(part_type,
part_size,
part_file);
@@ -2031,11 +2070,6 @@
}
if (part_init_file) {
- if (!path_exists(part_init_file)) {
- PANIC("Invalid initial %s image path: %s",
- part_name,
- part_init_file);
- }
pstrcat(tmp, sizeof tmp, ",initfile=");
pstrcat(tmp, sizeof tmp, part_init_file);
}
@@ -2046,9 +2080,6 @@
pstrcat(tmp, sizeof tmp,",pagesize=512,extrasize=0");
}
- VERBOSE_PRINT(init, "%s partition format: %s", part_name,
- androidPartitionType_toString(part_type));
-
nand_add_dev(tmp);
}
@@ -3041,17 +3072,19 @@
/* Initialize system partition image */
android_nand_add_image("system",
- ANDROID_PARTITION_TYPE_UNKNOWN,
- android_hw->disk_systemPartition_size,
- android_hw->disk_systemPartition_path,
- android_hw->disk_systemPartition_initPath);
+ ANDROID_PARTITION_TYPE_UNKNOWN,
+ ANDROID_PARTITION_OPEN_MODE_MUST_EXIST,
+ android_hw->disk_systemPartition_size,
+ android_hw->disk_systemPartition_path,
+ android_hw->disk_systemPartition_initPath);
/* Initialize data partition image */
android_nand_add_image("userdata",
- ANDROID_PARTITION_TYPE_UNKNOWN,
- android_hw->disk_dataPartition_size,
- android_hw->disk_dataPartition_path,
- android_hw->disk_dataPartition_initPath);
+ ANDROID_PARTITION_TYPE_UNKNOWN,
+ ANDROID_PARTITION_OPEN_MODE_CREATE_IF_NEEDED,
+ android_hw->disk_dataPartition_size,
+ android_hw->disk_dataPartition_path,
+ android_hw->disk_dataPartition_initPath);
/* Initialize cache partition image, if any. Its type depends on the
* kernel version. For anything >= 3.10, it must be EXT4, or
@@ -3063,11 +3096,17 @@
ANDROID_PARTITION_TYPE_YAFFS2 :
ANDROID_PARTITION_TYPE_EXT4;
+ AndroidPartitionOpenMode cache_part_mode =
+ (android_op_wipe_data ?
+ ANDROID_PARTITION_OPEN_MODE_MUST_WIPE :
+ ANDROID_PARTITION_OPEN_MODE_CREATE_IF_NEEDED);
+
android_nand_add_image("cache",
- cache_part_type,
- android_hw->disk_cachePartition_size,
- android_hw->disk_cachePartition_path,
- NULL);
+ cache_part_type,
+ cache_part_mode,
+ android_hw->disk_cachePartition_size,
+ android_hw->disk_cachePartition_path,
+ NULL);
}
/* Init SD-Card stuff. For Android, it is always hda */