recovery: Update recovery from CM.
Change-Id: Ibda5ba8bbfc93ef6ff565128b63adc2991218a70
diff --git a/Android.mk b/Android.mk
index 0179dc0..3f9f1e8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -26,12 +26,12 @@
LOCAL_FORCE_STATIC_EXECUTABLE := true
-RECOVERY_VERSION := ClockworkMod Recovery v3.0.0.6
+RECOVERY_VERSION := ClockworkMod Recovery v3.0.2.4
LOCAL_CFLAGS += -DRECOVERY_VERSION="$(RECOVERY_VERSION)"
RECOVERY_API_VERSION := 2
LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION)
-BOARD_RECOVERY_DEFINES := BOARD_HAS_NO_SELECT_BUTTON BOARD_HAS_SMALL_RECOVERY BOARD_LDPI_RECOVERY
+BOARD_RECOVERY_DEFINES := BOARD_HAS_NO_SELECT_BUTTON BOARD_HAS_SMALL_RECOVERY BOARD_LDPI_RECOVERY BOARD_UMS_LUNFILE
$(foreach board_define,$(BOARD_RECOVERY_DEFINES), \
$(if $($(board_define)), \
diff --git a/bootloader.c b/bootloader.c
index f3dc268..d455923 100644
--- a/bootloader.c
+++ b/bootloader.c
@@ -40,7 +40,6 @@
LOGE("unknown misc partition fs_type \"%s\"\n", v->fs_type);
return -1;
}
- LOGE("no misc partition\n");
return -1;
}
@@ -56,7 +55,6 @@
LOGE("unknown misc partition fs_type \"%s\"\n", v->fs_type);
return -1;
}
- LOGE("no misc partition\n");
return -1;
}
diff --git a/common.h b/common.h
index 5d24881..77cf143 100644
--- a/common.h
+++ b/common.h
@@ -113,6 +113,10 @@
// == "ext4" or "vfat" and mounting
// 'device' fails
const char* fs_type2;
+
+ const char* fs_options;
+
+ const char* fs_options2;
} Volume;
#endif // RECOVERY_COMMON_H
diff --git a/default_recovery_ui.c b/default_recovery_ui.c
index 9c192a2..6d61581 100644
--- a/default_recovery_ui.c
+++ b/default_recovery_ui.c
@@ -30,6 +30,7 @@
"backup and restore",
"mounts and storage",
"advanced",
+ "power off",
NULL };
int device_recovery_start() {
@@ -42,7 +43,8 @@
return 1;
// allow toggling of the display if the correct key is pressed, and the display toggle is allowed or the display is currently off
if (ui_get_showing_back_button()) {
- return get_allow_toggle_display() && (key_code == KEY_HOME || key_code == KEY_MENU || key_code == KEY_END);
+ return 0;
+ //return get_allow_toggle_display() && (key_code == KEY_HOME || key_code == KEY_MENU || key_code == KEY_END);
}
return get_allow_toggle_display() && (key_code == KEY_HOME || key_code == KEY_MENU || key_code == KEY_POWER || key_code == KEY_END);
}
@@ -57,11 +59,13 @@
case KEY_CAPSLOCK:
case KEY_DOWN:
case KEY_VOLUMEDOWN:
+ case KEY_MENU:
return HIGHLIGHT_DOWN;
case KEY_LEFTSHIFT:
case KEY_UP:
case KEY_VOLUMEUP:
+ case KEY_HOME:
return HIGHLIGHT_UP;
case KEY_POWER:
@@ -82,9 +86,14 @@
case KEY_END:
case KEY_BACKSPACE:
- case KEY_BACK:
+ case KEY_SEARCH:
+ if (ui_get_showing_back_button()) {
+ return SELECT_ITEM;
+ }
if (!get_allow_toggle_display())
return GO_BACK;
+ case KEY_BACK:
+ return GO_BACK;
}
}
diff --git a/edifyscripting.c b/edifyscripting.c
index 7d0d728..83f089f 100644
--- a/edifyscripting.c
+++ b/edifyscripting.c
@@ -134,6 +134,14 @@
free(path);
return StringValue(strdup(""));
}
+
+ if (strcmp(path, "/data") == 0 && has_datadata()) {
+ ui_print("Formatting /datadata...\n", path);
+ if (0 != format_volume("/datadata")) {
+ free(path);
+ return StringValue(strdup(""));
+ }
+ }
done:
return StringValue(strdup(path));
diff --git a/extendedcommands.c b/extendedcommands.c
index 1ce3bf1..717d8d2 100644
--- a/extendedcommands.c
+++ b/extendedcommands.c
@@ -340,12 +340,15 @@
nandroid_restore(file, 1, 1, 1, 1, 1, 0);
}
+#ifndef BOARD_UMS_LUNFILE
+#define BOARD_UMS_LUNFILE "/sys/devices/platform/usb_mass_storage/lun0/file"
+#endif
+
void show_mount_usb_storage_menu()
{
int fd;
Volume *vol = volume_for_path("/sdcard");
- if ((fd = open("/sys/devices/platform/usb_mass_storage/lun0/file",
- O_WRONLY)) < 0) {
+ if ((fd = open(BOARD_UMS_LUNFILE, O_WRONLY)) < 0) {
LOGE("Unable to open ums lunfile (%s)", strerror(errno));
return -1;
}
@@ -371,7 +374,7 @@
break;
}
- if ((fd = open("/sys/devices/platform/usb_mass_storage/lun0/file", O_WRONLY)) < 0) {
+ if ((fd = open(BOARD_UMS_LUNFILE, O_WRONLY)) < 0) {
LOGE("Unable to open ums lunfile (%s)", strerror(errno));
return -1;
}
@@ -473,6 +476,17 @@
//#define DEVICE_COUNT 4
//#define MMC_COUNT 2
+typedef struct {
+ char mount[255];
+ char unmount[255];
+ Volume* v;
+} MountMenuEntry;
+
+typedef struct {
+ char txt[255];
+ Volume* v;
+} FormatMenuEntry;
+
void show_partition_menu()
{
static char* headers[] = { "Mounts and Storage Menu",
@@ -480,87 +494,118 @@
NULL
};
+ static MountMenuEntry* mount_menue = NULL;
+ static FormatMenuEntry* format_menue = NULL;
+
typedef char* string;
- string mounts[][3] = {
- { "mount /system", "unmount /system", "/system" },
- { "mount /data", "unmount /data", "/data" },
- { "mount /cache", "unmount /cache", "/cache" },
- { "mount /sdcard", "unmount /sdcard", "/sdcard" },
-#ifdef BOARD_HAS_SDCARD_INTERNAL
- { "mount /emmc", "unmount /emmc", "/emmc" },
-#endif
- { "mount /sd-ext", "unmount /sd-ext", "/sd-ext" }
- };
- string devices[][2] = {
- { "format boot", "/boot" },
- { "format system", "/system" },
- { "format data", "/data" },
- { "format cache", "/cache" },
- { "format sdcard", "/sdcard" },
- { "format sd-ext", "/sd-ext" },
-#ifdef BOARD_HAS_SDCARD_INTERNAL
- { "format internal sdcard", "/emmc" }
-#endif
- };
+ int i, mountable_volumes, formatable_volumes;
+ int num_volumes;
+ Volume* device_volumes;
- const int MOUNTABLE_COUNT = sizeof(mounts) / sizeof(string) / 3;
- const int DEVICE_COUNT = sizeof(devices) / sizeof(string) / 2;
+ num_volumes = get_num_volumes();
+ device_volumes = get_device_volumes();
+
+ string options[255];
+
+ if(!device_volumes)
+ return;
+
+ mountable_volumes = 0;
+ formatable_volumes = 0;
+
+ mount_menue = malloc(num_volumes * sizeof(MountMenuEntry));
+ format_menue = malloc(num_volumes * sizeof(FormatMenuEntry));
+
+ for (i = 0; i < num_volumes; ++i) {
+ Volume* v = &device_volumes[i];
+ if(strcmp("ramdisk", v->fs_type) != 0 && strcmp("mtd", v->fs_type) != 0 && strcmp("emmc", v->fs_type) != 0 && strcmp("bml", v->fs_type) != 0)
+ {
+ sprintf(&mount_menue[mountable_volumes].mount, "mount %s", v->mount_point);
+ sprintf(&mount_menue[mountable_volumes].unmount, "unmount %s", v->mount_point);
+ mount_menue[mountable_volumes].v = &device_volumes[i];
+ ++mountable_volumes;
+ sprintf(&format_menue[formatable_volumes].txt, "format %s", v->mount_point);
+ format_menue[formatable_volumes].v = &device_volumes[i];
+ ++formatable_volumes;
+ }
+ else if (strcmp("ramdisk", v->fs_type) != 0 && strcmp("misc", v->mount_point) != 0 && strcmp("mtd", v->fs_type) == 0)
+ {
+ sprintf(&format_menue[formatable_volumes].txt, "format %s", v->mount_point);
+ format_menue[formatable_volumes].v = &device_volumes[i];
+ ++formatable_volumes;
+ }
+ }
+
static char* confirm_format = "Confirm format?";
static char* confirm = "Yes - Format";
for (;;)
{
- int ismounted[MOUNTABLE_COUNT];
- int i;
- static string options[MOUNTABLE_COUNT + DEVICE_COUNT + 1 + 1]; // mountables, format mtds, format mmcs, usb storage, null
- for (i = 0; i < MOUNTABLE_COUNT; i++)
- {
- ismounted[i] = is_path_mounted(mounts[i][2]);
- options[i] = ismounted[i] ? mounts[i][1] : mounts[i][0];
- }
- for (i = 0; i < DEVICE_COUNT; i++)
- {
- options[MOUNTABLE_COUNT + i] = devices[i][0];
- }
+ for (i = 0; i < mountable_volumes; i++)
+ {
+ MountMenuEntry* e = &mount_menue[i];
+ Volume* v = e->v;
+ if(is_path_mounted(v->mount_point))
+ options[i] = e->unmount;
+ else
+ options[i] = e->mount;
+ }
- options[MOUNTABLE_COUNT + DEVICE_COUNT] = "mount USB storage";
- options[MOUNTABLE_COUNT + DEVICE_COUNT + 1] = NULL;
+ for (i = 0; i < formatable_volumes; i++)
+ {
+ FormatMenuEntry* e = &format_menue[i];
- int chosen_item = get_menu_selection(headers, options, 0, 0);
+ options[mountable_volumes+i] = e->txt;
+ }
+
+ options[mountable_volumes+formatable_volumes] = "mount USB storage";
+ options[mountable_volumes+formatable_volumes + 1] = NULL;
+
+ int chosen_item = get_menu_selection(headers, &options, 0, 0);
if (chosen_item == GO_BACK)
break;
- if (chosen_item == MOUNTABLE_COUNT + DEVICE_COUNT)
+ if (chosen_item == (mountable_volumes+formatable_volumes))
{
show_mount_usb_storage_menu();
}
- else if (chosen_item < MOUNTABLE_COUNT)
+ else if (chosen_item < mountable_volumes)
{
- if (ismounted[chosen_item])
+ MountMenuEntry* e = &mount_menue[chosen_item];
+ Volume* v = e->v;
+
+ if (is_path_mounted(v->mount_point))
{
- if (0 != ensure_path_unmounted(mounts[chosen_item][2]))
- ui_print("Error unmounting %s!\n", mounts[chosen_item][2]);
+ if (0 != ensure_path_unmounted(v->mount_point))
+ ui_print("Error unmounting %s!\n", v->mount_point);
}
else
{
- if (0 != ensure_path_mounted(mounts[chosen_item][2]))
- ui_print("Error mounting %s!\n", mounts[chosen_item][2]);
+ if (0 != ensure_path_mounted(v->mount_point))
+ ui_print("Error mounting %s!\n", v->mount_point);
}
}
- else if (chosen_item < MOUNTABLE_COUNT + DEVICE_COUNT)
+ else if (chosen_item < (mountable_volumes + formatable_volumes))
{
- chosen_item = chosen_item - MOUNTABLE_COUNT;
+ chosen_item = chosen_item - mountable_volumes;
+ FormatMenuEntry* e = &format_menue[chosen_item];
+ Volume* v = e->v;
+
if (!confirm_selection(confirm_format, confirm))
continue;
- ui_print("Formatting %s...\n", devices[chosen_item][1]);
- if (0 != format_volume(devices[chosen_item][1]))
- ui_print("Error formatting %s!\n", devices[chosen_item][1]);
+ ui_print("Formatting %s...\n", v->mount_point);
+ if (0 != format_volume(v->mount_point))
+ ui_print("Error formatting %s!\n", v->mount_point);
else
ui_print("Done.\n");
}
}
+
+ free(mount_menue);
+ free(format_menue);
+
}
#define EXTENDEDCOMMAND_SCRIPT "/cache/recovery/extendedcommand"
@@ -974,7 +1019,8 @@
fprintf(file, "%s ", device);
fprintf(file, "%s ", path);
- fprintf(file, "%s rw\n", vol->fs_type2 != NULL ? "auto" : vol->fs_type);
+ // special case rfs cause auto will mount it as vfat on samsung.
+ fprintf(file, "%s rw\n", vol->fs_type2 != NULL && strcmp(vol->fs_type, "rfs") != 0 ? "auto" : vol->fs_type);
}
void create_fstab()
@@ -1026,6 +1072,9 @@
void process_volumes() {
create_fstab();
+ return;
+
+ // dead code.
if (device_flash_type() != BML)
return;
@@ -1127,4 +1176,4 @@
if (strstr(file_data, "androidboot.mode=offmode_charging") != NULL)
reboot(RB_POWER_OFF);
- }
\ No newline at end of file
+ }
diff --git a/flashutils/flashutils.c b/flashutils/flashutils.c
index b71d4fa..0b1467e 100644
--- a/flashutils/flashutils.c
+++ b/flashutils/flashutils.c
@@ -69,9 +69,21 @@
return (pid == -1 ? -1 : pstat);
}
-int restore_raw_partition(const char *partition, const char *filename)
+static int detect_partition(const char *partition)
{
int type = device_flash_type();
+ if (strstr(partition, "/dev/block/mtd") != NULL)
+ type = MTD;
+ else if (strstr(partition, "/dev/block/mmc") != NULL)
+ type = MMC;
+ else if (strstr(partition, "/dev/block/bml") != NULL)
+ type = BML;
+
+ return type;
+}
+int restore_raw_partition(const char *partition, const char *filename)
+{
+ int type = detect_partition(partition);
switch (type) {
case MTD:
return cmd_mtd_restore_raw_partition(partition, filename);
@@ -86,7 +98,7 @@
int backup_raw_partition(const char *partition, const char *filename)
{
- int type = device_flash_type();
+ int type = detect_partition(partition);
switch (type) {
case MTD:
return cmd_mtd_backup_raw_partition(partition, filename);
@@ -101,7 +113,7 @@
int erase_raw_partition(const char *partition)
{
- int type = device_flash_type();
+ int type = detect_partition(partition);
switch (type) {
case MTD:
return cmd_mtd_erase_raw_partition(partition);
@@ -116,7 +128,7 @@
int erase_partition(const char *partition, const char *filesystem)
{
- int type = device_flash_type();
+ int type = detect_partition(partition);
switch (type) {
case MTD:
return cmd_mtd_erase_partition(partition, filesystem);
@@ -131,7 +143,7 @@
int mount_partition(const char *partition, const char *mount_point, const char *filesystem, int read_only)
{
- int type = device_flash_type();
+ int type = detect_partition(partition);
switch (type) {
case MTD:
return cmd_mtd_mount_partition(partition, mount_point, filesystem, read_only);
diff --git a/mmcutils/Android.mk b/mmcutils/Android.mk
index f1fe294..0046dc9 100644
--- a/mmcutils/Android.mk
+++ b/mmcutils/Android.mk
@@ -4,6 +4,10 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
+ifeq ($(BOARD_HAS_LARGE_FILESYSTEM),true)
+LOCAL_CFLAGS += -DBOARD_HAS_LARGE_FILESYSTEM
+endif
+
LOCAL_SRC_FILES := \
mmcutils.c
diff --git a/mmcutils/mmcutils.c b/mmcutils/mmcutils.c
index e0efe55..76b8ff8 100644
--- a/mmcutils/mmcutils.c
+++ b/mmcutils/mmcutils.c
@@ -340,13 +340,18 @@
int
format_ext3_device (const char *device) {
- // Run mke2fs
+#ifdef BOARD_HAS_LARGE_FILESYSTEM
+ char *const mke2fs[] = {MKE2FS_BIN, "-j", "-q", device, NULL};
+ char *const tune2fs[] = {TUNE2FS_BIN, "-C", "1", device, NULL};
+#else
char *const mke2fs[] = {MKE2FS_BIN, "-j", device, NULL};
+ char *const tune2fs[] = {TUNE2FS_BIN, "-j", "-C", "1", device, NULL};
+#endif
+ // Run mke2fs
if(run_exec_process(mke2fs))
return -1;
// Run tune2fs
- char *const tune2fs[] = {TUNE2FS_BIN, "-j", "-C", "1", device, NULL};
if(run_exec_process(tune2fs))
return -1;
@@ -464,9 +469,8 @@
}
-// TODO: refactor this to not be a giant copy paste mess
int
-mmc_raw_dump (const MmcPartition *partition, char *out_file) {
+mmc_raw_dump_internal (const char* in_file, const char *out_file) {
int ch;
FILE *in;
FILE *out;
@@ -475,7 +479,6 @@
unsigned sz = 0;
unsigned i;
int ret = -1;
- char *in_file = partition->device_index;
in = fopen ( in_file, "r" );
if (in == NULL)
@@ -516,6 +519,12 @@
}
+// TODO: refactor this to not be a giant copy paste mess
+int
+mmc_raw_dump (const MmcPartition *partition, char *out_file) {
+ return mmc_raw_dump_internal(partition->device_index, out_file);
+}
+
int
mmc_raw_read (const MmcPartition *partition, char *data, int data_size) {
@@ -575,33 +584,36 @@
int cmd_mmc_restore_raw_partition(const char *partition, const char *filename)
{
- mmc_scan_partitions();
- const MmcPartition *p;
- p = mmc_find_partition_by_name(partition);
- if (p == NULL)
- return -1;
- return mmc_raw_copy(p, filename);
+ if (partition[0] != '/') {
+ mmc_scan_partitions();
+ const MmcPartition *p;
+ p = mmc_find_partition_by_name(partition);
+ if (p == NULL)
+ return -1;
+ return mmc_raw_copy(p, filename);
+ }
+ else {
+ return mmc_raw_dump_internal(filename, partition);
+ }
}
int cmd_mmc_backup_raw_partition(const char *partition, const char *filename)
{
- mmc_scan_partitions();
- const MmcPartition *p;
- p = mmc_find_partition_by_name(partition);
- if (p == NULL)
- return -1;
- return mmc_raw_dump(p, filename);
+ if (partition[0] != '/') {
+ mmc_scan_partitions();
+ const MmcPartition *p;
+ p = mmc_find_partition_by_name(partition);
+ if (p == NULL)
+ return -1;
+ return mmc_raw_dump(p, filename);
+ }
+ else {
+ return mmc_raw_dump_internal(partition, filename);
+ }
}
int cmd_mmc_erase_raw_partition(const char *partition)
{
- mmc_scan_partitions();
- const MmcPartition *p;
- p = mmc_find_partition_by_name(partition);
- if (p == NULL)
- return -1;
-
- // TODO: implement raw wipe
return 0;
}
diff --git a/nandroid.c b/nandroid.c
index 45417fb..933faa3 100644
--- a/nandroid.c
+++ b/nandroid.c
@@ -110,6 +110,7 @@
char tmp[PATH_MAX];
int ret;
if (strcmp(vol->fs_type, "mtd") == 0 ||
+ strcmp(vol->fs_type, "bml") == 0 ||
strcmp(vol->fs_type, "emmc") == 0) {
const char* name = basename(root);
sprintf(tmp, "%s/%s.img", backup_path, name);
@@ -153,14 +154,15 @@
if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
return ret;
- if (0 == (ret = get_partition_device("wimax", tmp)))
+ Volume *vol = volume_for_path("/wimax");
+ if (vol != NULL && 0 == stat(vol->device, &s))
{
char serialno[PROPERTY_VALUE_MAX];
ui_print("Backing up WiMAX...\n");
serialno[0] = 0;
property_get("ro.serialno", serialno, "");
sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);
- ret = backup_raw_partition("wimax", tmp);
+ ret = backup_raw_partition(vol->device, tmp);
if (0 != ret)
return print_and_error("Error while dumping WiMAX image!\n");
}
@@ -176,8 +178,7 @@
return ret;
}
- struct stat st;
- if (0 != stat("/sdcard/.android_secure", &st))
+ if (0 != stat("/sdcard/.android_secure", &s))
{
ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n");
}
@@ -190,8 +191,8 @@
if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
return ret;
- Volume *vol = volume_for_path("/sd-ext");
- if (vol == NULL || 0 != stat(vol->device, &st))
+ vol = volume_for_path("/sd-ext");
+ if (vol == NULL || 0 != stat(vol->device, &s))
{
ui_print("No sd-ext found. Skipping backup of sd-ext.\n");
}
@@ -282,6 +283,7 @@
// see if we need a raw restore (mtd)
char tmp[PATH_MAX];
if (strcmp(vol->fs_type, "mtd") == 0 ||
+ strcmp(vol->fs_type, "bml") == 0 ||
strcmp(vol->fs_type, "emmc") == 0) {
int ret;
const char* name = basename(root);
@@ -322,7 +324,9 @@
if (restore_boot && NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot")))
return ret;
- if (restore_wimax && 0 == (ret = get_partition_device("wimax", tmp)))
+ struct stat s;
+ Volume *vol = volume_for_path("/wimax");
+ if (restore_wimax && vol != NULL && 0 == stat(vol->device, &s))
{
char serialno[PROPERTY_VALUE_MAX];
@@ -344,7 +348,7 @@
if (0 != (ret = format_volume("/wimax")))
return print_and_error("Error while formatting wimax!\n");
ui_print("Restoring WiMAX image...\n");
- if (0 != (ret = restore_raw_partition("wimax", tmp)))
+ if (0 != (ret = restore_raw_partition(vol->device, tmp)))
return ret;
}
}
diff --git a/recovery.c b/recovery.c
index bb4c1be..963c724 100644
--- a/recovery.c
+++ b/recovery.c
@@ -61,6 +61,7 @@
static const char *LAST_LOG_FILE = "/cache/recovery/last_log";
static const char *SDCARD_ROOT = "/sdcard";
static int allow_display_toggle = 1;
+static int poweroff = 0;
static const char *SDCARD_PACKAGE_FILE = "/sdcard/update.zip";
static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
static const char *SIDELOAD_TEMP_DIR = "/tmp/sideload";
@@ -707,6 +708,7 @@
switch (chosen_item) {
case ITEM_REBOOT:
+ poweroff=0;
return;
case ITEM_WIPE_DATA:
@@ -751,6 +753,9 @@
case ITEM_ADVANCED:
show_advanced_menu();
break;
+ case ITEM_POWEROFF:
+ poweroff=1;
+ return;
}
}
}
@@ -782,6 +787,9 @@
return nandroid_main(argc, argv);
if (strstr(argv[0], "reboot"))
return reboot_main(argc, argv);
+ if (strstr(argv[0], "poweroff")){
+ return reboot_main(argc, argv);
+ }
if (strstr(argv[0], "setprop"))
return setprop_main(argc, argv);
return busybox_driver(argc, argv);
@@ -939,9 +947,12 @@
// Otherwise, get ready to boot the main system...
finish_recovery(send_intent);
- ui_print("Rebooting...\n");
+ if(!poweroff)
+ ui_print("Rebooting...\n");
+ else
+ ui_print("Shutting down...\n");
sync();
- reboot(RB_AUTOBOOT);
+ reboot((!poweroff) ? RB_AUTOBOOT : RB_POWER_OFF);
return EXIT_SUCCESS;
}
diff --git a/recovery_ui.h b/recovery_ui.h
index f34365f..50af45b 100644
--- a/recovery_ui.h
+++ b/recovery_ui.h
@@ -74,6 +74,7 @@
#define ITEM_NANDROID 5
#define ITEM_PARTITION 6
#define ITEM_ADVANCED 7
+#define ITEM_POWEROFF 8
// Header text to display above the main menu.
extern char* MENU_HEADERS[];
diff --git a/roots.c b/roots.c
index 4ef5c37..a3c4677 100644
--- a/roots.c
+++ b/roots.c
@@ -28,8 +28,30 @@
#include "common.h"
#include "make_ext4fs.h"
-static int num_volumes = 0;
-static Volume* device_volumes = NULL;
+int num_volumes;
+Volume* device_volumes;
+
+int get_num_volumes() {
+ return num_volumes;
+}
+
+Volume* get_device_volumes() {
+ return device_volumes;
+}
+
+static int is_null(const char* sz) {
+ if (sz == NULL)
+ return 1;
+ if (strcmp("NULL", sz) == 0)
+ return 1;
+ return 0;
+}
+
+static char* dupe_string(const char* sz) {
+ if (is_null(sz))
+ return NULL;
+ return strdup(sz);
+}
void load_volume_table() {
int alloc = 2;
@@ -40,6 +62,8 @@
device_volumes[0].fs_type = "ramdisk";
device_volumes[0].device = NULL;
device_volumes[0].device2 = NULL;
+ device_volumes[0].fs_options = NULL;
+ device_volumes[0].fs_options2 = NULL;
num_volumes = 1;
FILE* fstab = fopen("/etc/recovery.fstab", "r");
@@ -63,6 +87,8 @@
// mounting the first one fails.
char* device2 = strtok(NULL, " \t\n");
char* fs_type2 = strtok(NULL, " \t\n");
+ char* fs_options = strtok(NULL, " \t\n");
+ char* fs_options2 = strtok(NULL, " \t\n");
if (mount_point && fs_type && device) {
while (num_volumes >= alloc) {
@@ -70,11 +96,20 @@
device_volumes = realloc(device_volumes, alloc*sizeof(Volume));
}
device_volumes[num_volumes].mount_point = strdup(mount_point);
- device_volumes[num_volumes].fs_type = fs_type2 != NULL ? strdup(fs_type2) : strdup(fs_type);
+ device_volumes[num_volumes].fs_type = !is_null(fs_type2) ? strdup(fs_type2) : strdup(fs_type);
device_volumes[num_volumes].device = strdup(device);
device_volumes[num_volumes].device2 =
- (device2 != NULL && strcmp(device2, "NULL") != 0) ? strdup(device2) : NULL;
- device_volumes[num_volumes].fs_type2 = fs_type2 != NULL ? strdup(fs_type) : NULL;
+ !is_null(device2) ? strdup(device2) : NULL;
+ device_volumes[num_volumes].fs_type2 = !is_null(fs_type2) ? strdup(fs_type) : NULL;
+
+ if (!is_null(fs_type2)) {
+ device_volumes[num_volumes].fs_options2 = dupe_string(fs_options);
+ device_volumes[num_volumes].fs_options = dupe_string(fs_options2);
+ }
+ else {
+ device_volumes[num_volumes].fs_options2 = NULL;
+ device_volumes[num_volumes].fs_options = dupe_string(fs_options);
+ }
++num_volumes;
} else {
LOGE("skipping malformed recovery.fstab line: %s\n", original);
@@ -107,11 +142,20 @@
return NULL;
}
-int try_mount(const char* device, const char* mount_point, const char* fs_type) {
+int try_mount(const char* device, const char* mount_point, const char* fs_type, const char* fs_options) {
if (device == NULL || mount_point == NULL || fs_type == NULL)
return -1;
- int ret = mount(device, mount_point, fs_type,
+ int ret = 0;
+ if (fs_options == NULL) {
+ ret = mount(device, mount_point, fs_type,
MS_NOATIME | MS_NODEV | MS_NODIRATIME, "");
+ }
+ else {
+ char mount_cmd[PATH_MAX];
+ sprintf(mount_cmd, "mount -t %s -o%s %s %s", fs_type, fs_options, device, mount_point);
+ LOGE("%s\n", mount_cmd);
+ ret = __system(mount_cmd);
+ }
if (ret == 0)
return 0;
LOGW("failed to mount %s (%s)\n", device, strerror(errno));
@@ -158,15 +202,15 @@
return mtd_mount_partition(partition, v->mount_point, v->fs_type, 0);
} else if (strcmp(v->fs_type, "ext4") == 0 ||
strcmp(v->fs_type, "ext3") == 0 ||
+ strcmp(v->fs_type, "rfs") == 0 ||
strcmp(v->fs_type, "vfat") == 0) {
- // try fs type 2 first
- if ((result = try_mount(v->device, v->mount_point, v->fs_type)) == 0)
+ if ((result = try_mount(v->device, v->mount_point, v->fs_type, v->fs_options)) == 0)
return 0;
- if ((result = try_mount(v->device2, v->mount_point, v->fs_type)) == 0)
+ if ((result = try_mount(v->device2, v->mount_point, v->fs_type, v->fs_options)) == 0)
return 0;
- if ((result = try_mount(v->device, v->mount_point, v->fs_type2)) == 0)
+ if ((result = try_mount(v->device, v->mount_point, v->fs_type2, v->fs_options2)) == 0)
return 0;
- if ((result = try_mount(v->device2, v->mount_point, v->fs_type2)) == 0)
+ if ((result = try_mount(v->device2, v->mount_point, v->fs_type2, v->fs_options2)) == 0)
return 0;
return result;
} else {
diff --git a/roots.h b/roots.h
index cf59bfd..7132fed 100644
--- a/roots.h
+++ b/roots.h
@@ -38,4 +38,8 @@
// it is mounted.
int format_volume(const char* volume);
+int get_num_volumes();
+
+Volume* get_device_volumes();
+
#endif // RECOVERY_ROOTS_H_
diff --git a/utilities/Android.mk b/utilities/Android.mk
index f6b6e64..251c9e6 100644
--- a/utilities/Android.mk
+++ b/utilities/Android.mk
@@ -42,4 +42,14 @@
LOCAL_SRC_FILES := $(LOCAL_MODULE)
include $(BUILD_PREBUILT)
+ifeq ($BOARD_HAS_LARGE_FILESYSTEM,true)
+include $(CLEAR_VARS)
+LOCAL_MODULE := mke2fs
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
+LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+endif
+
endif
diff --git a/utilities/mke2fs b/utilities/mke2fs
new file mode 100644
index 0000000..6e415b8
--- /dev/null
+++ b/utilities/mke2fs
Binary files differ