Example #1
0
int ubi_format(const char *mount_point) {
    //Detach UBI volume before formating
    printf("It's in ubi_format!!\n");
    const char* partition_name;
    char mtd_dev_name[20];
    const MtdPartition *partition;
    int32_t mtd_num;
    int32_t ubi_num = -1;

    if (!strcmp(mount_point, "/system")) {
        ubi_num = 0;
        partition_name = "system";
    }

    if (!strcmp(mount_point, "/data")) {
        ubi_num = 1;
        partition_name = "userdata";
    }

    if (!strcmp(mount_point, "/cache") || !strcmp(mount_point, "/.cache")) {
        ubi_num = 2;
        partition_name = "cache";
    }


    if (ubi_num != -1) {
        ubi_detach_dev(ubi_num);
        printf("Back to ubi_format!!\n");
    } else {
        printf("Can not find a ubi device![%s], error:%s\n", mount_point, strerror(errno));
        return -1;
    }

    //Run-time get mtd_dev_name
    mtd_scan_partitions();
    partition = mtd_find_partition_by_name(partition_name);
    if (partition == NULL) {
        LOGE("failed to find \"%s\" partition to mount at \"%s\"\n",
                partition_name,mount_point);
        return -1;
    }

    mtd_num = mtd_part_to_number(partition);
    printf("mtd_num = %d\n", mtd_num);
    sprintf(mtd_dev_name, "/dev/mtd/mtd%d", mtd_num);

    printf("Formatting %s -> %s\n", mount_point, mtd_dev_name);

    const char* binary_path = "/sbin/ubiformat";
    const char* skip_questions = "-y";

    int check;
    check = chmod(binary_path, 0777);
    printf("chmod = %d\n", check);

    const char** args = (const char**)malloc(sizeof(char*) * 4);
    args[0] = binary_path;
    args[1] = (const char *)mtd_dev_name;
    args[2] = skip_questions;
    args[3] = 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 -1;
    }


    //Attatch UBI device & Make UBI volume
    int n = -1;
    n = ubi_attach_mtd_user(mount_point);

    if ((n != -1) && (n < 4)) {
        printf("Try to attatch /dev/ubi%d_0... volume is attached \n", n);
    } else {
        LOGE("failed to attach /dev/ubi%d_0%s\n", n);
        return -1;
    }

    return 0;
}
Example #2
0
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;
}
Example #3
0
int ensure_path_mounted(const char* path) {
    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.
        return 0;
    }

    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) {
#if defined(CACHE_MERGE_SUPPORT)
        if (strncmp(path, "/cache", 6) == 0) {
            if (symlink(DATA_CACHE_ROOT, "/cache")) {
                if (errno != EEXIST) {
                    LOGE("create symlink from %s to %s failed(%s)\n",
                            DATA_CACHE_ROOT, "/cache", strerror(errno));
                    return -1;
                }
            }
        }
#endif
        // volume is already mounted
        return 0;
    }

    mkdir(v->mount_point, 0755);  // in case it doesn't already exist

#if defined (UBIFS_SUPPORT)
    if (strcmp(v->fs_type, "ubifs") == 0) {

        printf("Trying to mount %s \n", v->mount_point);

        //Attatch UBI device & Make UBI volum
        int n = -1;
        n = ubi_attach_mtd_user(v->mount_point);

        if ((n != -1) && (n < 4)) {
            printf("Try to attatch %s \n", v->blk_device);
            printf("/dev/ubi%d_0 is attached \n", n);
        } else {
            LOGE("failed to attach %s\n", v->blk_device);
        }


        //Mount UBI volume
        const unsigned long flags = MS_NOATIME | MS_NODEV | MS_NODIRATIME;
        char tmp[64];
        sprintf(tmp, "/dev/ubi%d_0", n);
        wait_for_file(tmp, 5);
        result = mount(tmp, v->mount_point, v->fs_type, flags, "");
        if (result < 0) {
            ubi_detach_dev(n);
            return -1;
        } else if (result == 0) {
            goto mount_done;  //Volume  successfully  mounted
        }

    }
#endif

    if (strcmp(v->fs_type, "yaffs2") == 0) {
        // mount an MTD partition as a YAFFS2 filesystem.
        mtd_scan_partitions();
        const MtdPartition* partition;
        partition = mtd_find_partition_by_name(v->blk_device);
        if (partition == NULL) {
            LOGE("failed to find \"%s\" partition to mount at \"%s\"\n",
                    v->blk_device, v->mount_point);
            return -1;
        }
        return mtd_mount_partition(partition, v->mount_point, v->fs_type, 0);
    } else if (strcmp(v->fs_type, "ext4") == 0 ||
               strcmp(v->fs_type, "squashfs") == 0 ||
               strcmp(v->fs_type, "vfat") == 0) {
        mt_ensure_dev_ready(v->mount_point);
        result = mount(v->blk_device, v->mount_point, v->fs_type,
                       v->flags, v->fs_options);
        if (result == 0) {
            goto mount_done;
        } else {
            result = mt_ensure_path_mounted(v);
            if (result == 0)
                goto mount_done;
        }
        LOGE("failed to mount %s (%s)\n", v->mount_point, strerror(errno));
        return -1;
    }

    LOGE("unknown fs_type \"%s\" for %s\n", v->fs_type, v->mount_point);
    return -1;

mount_done:
#if defined(CACHE_MERGE_SUPPORT)
    if (strcmp(v->mount_point, "/data") == 0) {
        if (mkdir(DATA_CACHE_ROOT, 0770)) {
            if (errno != EEXIST) {
                LOGE("mkdir %s error: %s\n", DATA_CACHE_ROOT, strerror(errno));
                return -1;
            } else if (need_clear_cache) {
                LOGI("cache exists, clear it...\n");
                if (remove_dir(DATA_CACHE_ROOT)) {
                    LOGE("remove_dir %s error: %s\n", DATA_CACHE_ROOT, strerror(errno));
                    return -1;
                }
                if (mkdir(DATA_CACHE_ROOT, 0770) != 0) {
                    LOGE("mkdir %s error: %s\n", DATA_CACHE_ROOT, strerror(errno));
                    return -1;
                }
            }
        }
        if (symlink(DATA_CACHE_ROOT, "/cache")) {
            if (errno != EEXIST) {
                LOGE("create symlink from %s to %s failed(%s)\n",
                        DATA_CACHE_ROOT, "/cache", strerror(errno));
                return -1;
            }
        }
        need_clear_cache = 0;
    }
#endif
    return 0;
}