Value* UnmountFn(const char* name, State* state, int argc, Expr* argv[]) { char* result = NULL; if (argc != 1) { return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc); } char* mount_point; if (ReadArgs(state, argv, 1, &mount_point) < 0) { return NULL; } if (strlen(mount_point) == 0) { ErrorAbort(state, "mount_point argument to unmount() can't be empty"); goto done; } scan_mounted_volumes(); const MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point); if (vol == NULL) { fprintf(stderr, "unmount of %s failed; no such volume\n", mount_point); result = strdup(""); } else { unmount_mounted_volume(vol); result = mount_point; } done: if (result != mount_point) free(mount_point); return StringValue(result); }
int ensure_path_unmounted(const char* path) { if (PartitionManager.UnMount_By_Path(path, true)) return 0; else return -1; Volume* v = volume_for_path(path); if (v == NULL) { LOGE("unknown volume for path [%s]\n", path); return -1; } if (strcmp(v->fs_type, "ramdisk") == 0) { // the ramdisk is always mounted; you can't unmount it. return -1; } int result; result = scan_mounted_volumes(); if (result < 0) { LOGE("failed to scan mounted volumes\n"); return -1; } const MountedVolume* mv = find_mounted_volume_by_mount_point(v->mount_point); if (mv == NULL) { // volume is already unmounted return 0; } return unmount_mounted_volume(mv); }
int ensure_path_unmounted(const char* path) { // if we are using /data/media, do not ever unmount volumes /data or /sdcard if (strstr(path, "/data") == path && is_data_media()) { return 0; } Volume* v = volume_for_path(path); if (v == NULL) { LOGE("unknown volume for path [%s]\n", path); return -1; } if (is_data_media_volume_path(path)) { return ensure_path_unmounted("/data"); } if (strcmp(v->fs_type, "ramdisk") == 0) { // the ramdisk is always mounted; you can't unmount it. return -1; } int result; result = scan_mounted_volumes(); if (result < 0) { LOGE("failed to scan mounted volumes\n"); return -1; } const MountedVolume* mv = find_mounted_volume_by_mount_point(v->mount_point); if (mv == NULL) { // volume is already unmounted return 0; } return unmount_mounted_volume(mv); }
int ensure_root_path_unmounted(const char *root_path) { const RootInfo *info = get_root_info_for_path(root_path); if (info == NULL) { return -1; } if (info->mount_point == NULL) { /* This root can't be mounted, so by definition it isn't. */ return 0; } //xxx if TMP: (or similar) just return error /* See if this root is already mounted. */ int ret = scan_mounted_volumes(); if (ret < 0) { return ret; } const MountedVolume *volume; volume = find_mounted_volume_by_mount_point(info->mount_point); if (volume == NULL) { /* It's not mounted. */ return 0; } return unmount_mounted_volume(volume); }
int ensure_path_unmounted(const char* path) { Volume* v = volume_for_path(path); #if defined(CACHE_MERGE_SUPPORT) if (strncmp(path, "/cache", 6) == 0) { unlink(path); return 0; } #endif if (v == NULL) { LOGE("unknown volume for path [%s]\n", path); return -1; } if (strcmp(v->fs_type, "ramdisk") == 0) { // the ramdisk is always mounted; you can't unmount it. return -1; } int result; result = scan_mounted_volumes(); if (result < 0) { LOGE("failed to scan mounted volumes\n"); return -1; } const MountedVolume* mv = find_mounted_volume_by_mount_point(v->mount_point); if (mv == NULL) { // volume is already unmounted return 0; } return unmount_mounted_volume(mv); }
static int replace_device_node(int num, struct stat* statbuf) { scan_mounted_volumes(); MountedVolume * mv = find_mounted_volume_by_real_node(part_table[num].path); if(mv!=NULL && unmount_mounted_volume(mv)!=0) { LOGE("could not unmount device!\n"); return -1; } unlink(part_table[num].path); if(mknod(part_table[num].path, statbuf->st_mode, statbuf->st_rdev)!=0) { LOGE("could not create node!\n"); return -1; } return 0; }
int ensure_volume_unmounted(fstab_rec* v, bool detach) { if (v == NULL) { LOGE("cannot unmount unknown volume\n"); return -1; } if (strcmp(v->fs_type, "ramdisk") == 0) { // the ramdisk is always mounted; you can't unmount it. return -1; } int result; result = scan_mounted_volumes(); if (result < 0) { LOGE("failed to scan mounted volumes\n"); return -1; } if (fs_mgr_is_voldmanaged(v)) { if (!strcmp(v->mount_point, "auto")) { return vold_unmount_auto_volume(v->label, 0, 1, detach); } return vold_unmount_volume(v->mount_point, 0, 1, detach); } const MountedVolume* mv = find_mounted_volume_by_mount_point(v->mount_point); if (mv == NULL) { // volume is already unmounted return 0; } if (detach) { result = unmount_mounted_volume_detach(mv); } else { result = unmount_mounted_volume(mv); } return result; }
int ensure_root_path_unmounted(const char *root_path) { /* See if this root is already mounted. */ int ret = scan_mounted_volumes(); if (ret < 0) { return ret; } const MountedVolume *volume; volume = find_mounted_volume_by_mount_point(root_path); if (volume == NULL) { /* It's not mounted. */ LOGD(TAG "The path %s is unmounted\n", root_path); return 0; } return unmount_mounted_volume(volume); }
int ensure_path_unmounted(const char* path) { // This is an old, common method for ensuring a flush sync(); sync(); if (DataManager_GetIntValue(TW_DONT_UNMOUNT_SYSTEM) == 1 && strncmp(path, "/system", 7) == 0) return 0; if ((DataManager_GetIntValue(TW_HAS_DATA_MEDIA) == 1 || DataManager_GetIntValue(TW_HAS_DUAL_STORAGE) == 1) && strncmp(path, "/sdcard", 7) == 0) { LOGI("Unmounting /sdcard (dual storage path code)\n"); return system("umount /sdcard");; } Volume* v = volume_for_path(path); if (v == NULL) { LOGE("unknown volume for path [%s]\n", path); return -1; } if (strcmp(v->fs_type, "ramdisk") == 0) { // the ramdisk is always mounted; you can't unmount it. return -1; } int result; result = scan_mounted_volumes(); if (result < 0) { LOGE("failed to scan mounted volumes\n"); return -1; } const MountedVolume* mv = find_mounted_volume_by_mount_point(v->mount_point); if (mv == NULL) { // volume is already unmounted return 0; } return unmount_mounted_volume(mv); }
int format_root_device(const char *root) { /* See if this root is already mounted. */ const MountedVolume *volume; char *filesystem; char *device; int ret = scan_mounted_volumes(); if (ret < 0) { LOGD(TAG "format_root_device: load mount info fail\n", root); return false; } volume = find_mounted_volume_by_mount_point(root); if (volume == NULL) { LOGD(TAG "The path %s is unmounted\n", root); return 0; } filesystem = strdup(volume->filesystem); device = strdup(volume->device); ret = unmount_mounted_volume(volume); if (ret < 0) { LOGD(TAG "format_root_device: can't unmount \"%s\"\n", root); return false; } LOGD(TAG "format_root_device : unmount %s scucess, type is %s\n", root, filesystem); if (!strcmp(filesystem, "yaffs2")) { LOGD(TAG "format yaffs2 partitions\n", root); /* Format the device. */ mtd_scan_partitions(); const MtdPartition *partition = NULL; if(!strcmp(root, DATA_PARTITION)) { LOGD(TAG "find the partition name is %s", root); partition = mtd_find_partition_by_name("userdata"); } if (partition == NULL) { LOGD(TAG "format_root_device: can't find mtd partition \"%s\"\n", root); return false; } MtdWriteContext *write = mtd_write_partition(partition); if (write == NULL) { LOGD(TAG "format_root_device: can't open \"%s\"\n", root); return false; } else if (mtd_erase_blocks(write, -1) == (off_t) - 1) { LOGD(TAG "format_root_device: can't erase \"%s\"\n", root); mtd_write_close(write); return false; } else if (mtd_write_close(write)) { LOGD(TAG "format_root_device: can't close \"%s\"\n", root); return false; } else { ret= true; } } else { if (!strcmp(filesystem, "ubifs")) { int ubi_num = -1, ubi_dev; int mtd_num = -1; char path[128]; char mtd_dev_name[128]; const char *binary_path = "/system/bin/ubiformat"; sscanf(device, "/dev/ubi%d_0", &ubi_num); if (ubi_num >= 0 && ubi_num <= 32) { LOGD(TAG "format_root_device: detach ubi device /dev/ubi%d_0\n", ubi_num); } else { LOGD(TAG "Can not find parse ubi num :%s\n", device); return false; } sprintf(path, "/sys/class/ubi/ubi%d/mtd_num", ubi_num); ubi_dev = open(path, O_RDONLY); if (ubi_dev != -1) { ret = read(ubi_dev, path, sizeof(path)); close(ubi_dev); if (ret > 0) { mtd_num = atoi(path); LOGD(TAG " %s mtd_num is %d \n", device, mtd_num); sprintf(mtd_dev_name, "/dev/mtd/mtd%d", mtd_num); } else { LOGD(TAG " read %s fail! \n", path); return false; } } else { LOGD(TAG " open %s fail! \n", path); return false; } ret = ubi_detach_dev(ubi_num); if (ret != 0) { LOGD(TAG "format_root_device: detach ubi device /dev/ubi%d_0 fail!ret=%d\n", ubi_num, ret); return false; } //int check; //check = chmod(binary_path, 0777); //printf("chmod = %d\n", check); const char **args = (const char **)malloc(sizeof(char *) * 3); args[0] = binary_path; args[1] = mtd_dev_name; args[2] = NULL; pid_t pid = fork(); if (pid == 0) { execv(binary_path, (char *const *)args); fprintf(stdout, "E:Can't run %s (%s)\n", binary_path, strerror(errno)); _exit(-1); } int status; waitpid(pid, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { LOGE("Error in ubiformat\n(Status %d)\n", WEXITSTATUS(status)); return false; } ret=true; } else { LOGD(TAG "format_root_device : unsupport filesystem %s\n", filesystem); return false; } } free(filesystem); free(device); return ret; }
Value* UpdateFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 7) { return ErrorAbort(state, "%s() expects 7 args, got %d", name, argc); } char* type = strrchr(name, '_'); if (type == NULL || *(type+1) == '\0') { return ErrorAbort(state, "%s() couldn't get type from function name", name); } ++type; Value* image; Value* width_string; Value* height_string; Value* bpp_string; Value* busy; Value* fail; Value* expected_sha1_string; if (ReadValueArgs(state, argv, 7, &image, &width_string, &height_string, &bpp_string, &busy, &fail, &expected_sha1_string) < 0) { return NULL; } // close the package ZipArchive* za = ((UpdaterInfo*)(state->cookie))->package_zip; mzCloseZipArchive(za); ((UpdaterInfo*)(state->cookie))->package_zip = NULL; // Try to unmount /cache. If we fail (because we're running in an // older recovery that still has the package file open), try to // remount it read-only. If that fails, abort. sync(); scan_mounted_volumes(); MountedVolume* vol = find_mounted_volume_by_mount_point("/cache"); int result = unmount_mounted_volume(vol); if (result != 0) { printf("%s(): failed to unmount cache (%d: %s)\n", name, result, strerror(errno)); result = remount_read_only(vol); if (result != 0) { printf("%s(): failed to remount cache (%d: %s)\n", name, result, strerror(errno)); return StringValue(strdup("")); } else { printf("%s(): remounted cache\n", name); } sync(); } else { printf("%s(): unmounted cache\n", name); } int width = 0, height = 0, bpp = 0; if (width_string->type != VAL_STRING || (width = strtol(width_string->data, NULL, 10)) == 0) { printf("%s(): bad width argument", name); } if (height_string->type != VAL_STRING || (height = strtol(height_string->data, NULL, 10)) == 0) { printf("%s(): bad height argument", name); } if (bpp_string->type != VAL_STRING || (bpp = strtol(bpp_string->data, NULL, 10)) == 0) { printf("%s(): bad bpp argument", name); } if (image->type != VAL_BLOB) { printf("image argument is not blob (is type %d)\n", image->type); goto done; } uint8_t expected_sha1[SHA_DIGEST_SIZE]; char* data = expected_sha1_string->data; if (expected_sha1_string->type != VAL_STRING || strlen(data) != SHA_DIGEST_SIZE*2) { printf("%s(): bad expected_sha1 argument", name); goto done; } printf("expected sha1 is: "); int i; for (i = 0; i < SHA_DIGEST_SIZE; ++i) { char temp = data[i*2+2]; data[i*2+2] = '\0'; expected_sha1[i] = strtol(data+i*2, NULL, 16); data[i*2+2] = temp; printf("%02x", expected_sha1[i]); } printf("\n"); install_firmware_update( type, image->data, image->size, width, height, bpp, busy->size > 0 ? busy->data : NULL, fail->size > 0 ? fail->data : NULL, "/tmp/recovery.log", expected_sha1); printf("%s: install_firmware_update returned!\n", name); done: FreeValue(image); FreeValue(width_string); FreeValue(height_string); FreeValue(bpp_string); FreeValue(busy); FreeValue(fail); // install_firmware_update should reboot. If it returns, it failed. return StringValue(strdup("")); }