int do_wait(int nargs, char **args)
{
    if (nargs == 2) {
        return wait_for_file(args[1], COMMAND_RETRY_TIMEOUT);
    } else if (nargs == 3) {
        return wait_for_file(args[1], atoi(args[2]));
    } else
        return -1;
}
Beispiel #2
0
static int mount_and_run(struct fstab *fstab)
{
    struct fstab_part *datap = fstab_find_first_by_path(fstab, "/data");
    if(!datap)
    {
        ERROR("Failed to find /data partition in fstab\n");
        return -1;
    }

    if(access(datap->device, R_OK) < 0)
    {
        INFO("Waiting for %s\n", datap->device);
        if(wait_for_file(datap->device, 5) < 0)
        {
            ERROR("Waiting too long for dev %s\n", datap->device);
            return -1;
        }
    }

    mkdir(REALDATA, 0755);

    if(try_mount_all_entries(fstab, datap) < 0)
    {
#ifndef MR_ENCRYPTION
        ERROR("Failed to mount /data with all possible filesystems!\n");
        return -1;
#else
        INFO("Failed to mount /data, trying encryption...\n");
        switch(encryption_before_mount(fstab))
        {
            case ENC_RES_ERR:
                ERROR("/data decryption failed!\n");
                return -1;
            case ENC_RES_BOOT_INTERNAL:
                return 0;
            default:
            case ENC_RES_OK:
            {
                if(try_mount_all_entries(fstab, datap) < 0)
                {
                    ERROR("Failed to mount decrypted /data with all possible filesystems!\n");
                    return -1;
                }
                break;
            }
        }
#endif
    }

    if(find_multirom() == -1)
    {
        ERROR("Could not find multirom folder!\n");
        return -1;
    }

    adb_init(path_multirom);
    run_multirom();
    adb_quit();
    return 0;
}
Beispiel #3
0
int do_wait(int nargs, char **args)
{
    if (nargs == 2) {
        return wait_for_file(args[1], COMMAND_RETRY_TIMEOUT);
    }
    return -1;
}
/* If tmp_mount_point is non-null, mount the filesystem there.  This is for the
 * tmp mount we do to check the user password
 */
int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
                    char *tmp_mount_point)
{
    int i = 0;
    int ret = -1;
    char *m;

    if (!fstab) {
        return ret;
    }

    for (i = 0; i < fstab->num_entries; i++) {
        if (!fs_match(fstab->recs[i].mount_point, n_name)) {
            continue;
        }

        /* We found our match */
        /* If this is a raw partition, report an error */
        if (!strcmp(fstab->recs[i].fs_type, "emmc") ||
            !strcmp(fstab->recs[i].fs_type, "mtd")) {
            ERROR("Cannot mount filesystem of type %s on %s\n",
                  fstab->recs[i].fs_type, n_blk_device);
            goto out;
        }

        /* First check the filesystem if requested */
        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
            wait_for_file(n_blk_device, WAIT_TIMEOUT);
        }

        if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
            check_fs(n_blk_device, fstab->recs[i].fs_type,
                     fstab->recs[i].mount_point);
        }

        /* Now mount it where requested */
        if (tmp_mount_point) {
            m = tmp_mount_point;
        } else {
            m = fstab->recs[i].mount_point;
        }
        if (mount(n_blk_device, m, fstab->recs[i].fs_type,
                  fstab->recs[i].flags, fstab->recs[i].fs_options)) {
            ERROR("Cannot mount filesystem on %s at %s\n",
                    n_blk_device, m);
            goto out;
        } else {
            ret = 0;
            goto out;
        }
    }

    /* We didn't find a match, say so and return an error */
    ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point);

out:
    return ret;
}
Beispiel #5
0
int fs_mgr_mount_all(char *fstab_file)
{
    int i = 0;
    int encrypted = 0;
    int ret = -1;
    int mret;
    struct fstab_rec *fstab = 0;

    if (!(fstab = read_fstab(fstab_file))) {
        return ret;
    }

    for (i = 0; fstab[i].blk_dev; i++) {
        if (fstab[i].fs_mgr_flags & MF_WAIT) {
            wait_for_file(fstab[i].blk_dev, WAIT_TIMEOUT);
        }

        if (fstab[i].fs_mgr_flags & MF_CHECK) {
            check_fs(fstab[i].blk_dev, fstab[i].type, fstab[i].mnt_point);
        }

        mret = mount(fstab[i].blk_dev, fstab[i].mnt_point, fstab[i].type,
                     fstab[i].flags, fstab[i].fs_options);
        if (!mret) {
            /* Success!  Go get the next one */
            continue;
        }

        /* mount(2) returned an error, check if it's encrypted and deal with it */
        if ((fstab[i].fs_mgr_flags & MF_CRYPT) && !partition_wiped(fstab[i].blk_dev)) {
            /* Need to mount a tmpfs at this mountpoint for now, and set
             * properties that vold will query later for decrypting
             */
            if (mount("tmpfs", fstab[i].mnt_point, "tmpfs",
                  MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS) < 0) {
                ERROR("Cannot mount tmpfs filesystem for encrypted fs at %s\n",
                        fstab[i].mnt_point);
                goto out;
            }
            encrypted = 1;
        } else {
            ERROR("Cannot mount filesystem on %s at %s\n",
                    fstab[i].blk_dev, fstab[i].mnt_point);
            goto out;
        }
    }

    if (encrypted) {
        ret = 1;
    } else {
        ret = 0;
    }

out:
    free_fstab(fstab);
    return ret;
}
static int wait_for_coldboot_done_action(int nargs, char **args)
{
    int ret;
    INFO("wait for %s\n", coldboot_done);
    ret = wait_for_file(coldboot_done, COMMAND_RETRY_TIMEOUT);
    if (ret)
        ERROR("Timed out waiting for %s\n", coldboot_done);
    return ret;
}
Beispiel #7
0
/* If tmp_mnt_point is non-null, mount the filesystem there.  This is for the
 * tmp mount we do to check the user password
 */
int fs_mgr_do_mount(char *fstab_file, char *n_name, char *n_blk_dev, char *tmp_mnt_point)
{
    int i = 0;
    int ret = -1;
    struct fstab_rec *fstab = 0;
    char *m;

    if (!(fstab = read_fstab(fstab_file))) {
        return ret;
    }

    for (i = 0; fstab[i].blk_dev; i++) {
        if (!fs_match(fstab[i].mnt_point, n_name)) {
            continue;
        }

        /* We found our match */
        /* First check the filesystem if requested */
        if (fstab[i].fs_mgr_flags & MF_WAIT) {
            wait_for_file(fstab[i].blk_dev, WAIT_TIMEOUT);
        }

        if (fstab[i].fs_mgr_flags & MF_CHECK) {
            check_fs(fstab[i].blk_dev, fstab[i].type, fstab[i].mnt_point);
        }

        /* Now mount it where requested */
        if (tmp_mnt_point) {
            m = tmp_mnt_point;
        } else {
            m = fstab[i].mnt_point;
        }
        if (mount(n_blk_dev, m, fstab[i].type,
                  fstab[i].flags, fstab[i].fs_options)) {
            ERROR("Cannot mount filesystem on %s at %s\n",
                    n_blk_dev, m);
            goto out;
        } else {
            ret = 0;
            goto out;
        }
    }

    /* We didn't find a match, say so and return an error */
    ERROR("Cannot find mount point %s in fstab\n", fstab[i].mnt_point);

out:
    free_fstab(fstab);
    return ret;
}
Beispiel #8
0
static int wait_for_coldboot_done_action(const std::vector<std::string>& args) {
    Timer t;

    NOTICE("Waiting for %s...\n", COLDBOOT_DONE);
    // Any longer than 1s is an unreasonable length of time to delay booting.
    // If you're hitting this timeout, check that you didn't make your
    // sepolicy regular expressions too expensive (http://b/19899875).
    if (wait_for_file(COLDBOOT_DONE, 1)) {
        ERROR("Timed out waiting for %s\n", COLDBOOT_DONE);
    }

    NOTICE("Waiting for %s took %.2fs.\n", COLDBOOT_DONE, t.duration());
    return 0;
}
Beispiel #9
0
static int run_core(void)
{
    int res = -1;
    struct fstab *fstab = NULL;

    if(wait_for_file("/dev/graphics/fb0", 5) < 0)
    {
        ERROR("Waiting too long for fb0");
        goto exit;
    }

#ifdef MR_POPULATE_BY_NAME_PATH
    Populate_ByName_using_emmc();
#endif

    fstab = fstab_auto_load();
    if(!fstab)
        goto exit;

#if 0
    fstab_dump(fstab); //debug
#endif

    // mount and run multirom from sdcard
    res = mount_and_run(fstab);
    if(res < 0 && mrom_is_second_boot())
    {
        ERROR("This is second boot and we couldn't mount /data, reboot!\n");
        sync();
        //android_reboot(ANDROID_RB_RESTART, 0, 0);
        android_reboot(ANDROID_RB_RESTART2, 0, "recovery"); // favour reboot to recovery, to avoid possible bootlooping
        while(1)
            sleep(1);
    }

    if(access(KEEP_REALDATA, F_OK) < 0) {
        umount(REALDATA);
        rmdir(REALDATA);
        encryption_destroy();
    }

    encryption_cleanup();

exit:
    if(fstab)
        fstab_destroy(fstab);

    return res;
}
Beispiel #10
0
static int ubi_dev_read_int(int dev, const char *file, int def)
{
    int fd, val = def;
    char path[128], buf[64];

    sprintf(path, UBI_SYS_PATH "/ubi%d/%s", dev, file);
    wait_for_file(path, 5);
    fd = open(path, O_RDONLY);
    if (fd == -1) {
        return val;
    }

    if (read(fd, buf, 64) > 0) {
        val = atoi(buf);
    }

    close(fd);
    return val;
}
Beispiel #11
0
/* If tmp_mount_point is non-null, mount the filesystem there.  This is for the
 * tmp mount we do to check the user password
 * If multiple fstab entries are to be mounted on "n_name", it will try to mount each one
 * in turn, and stop on 1st success, or no more match.
 */
int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
                    char *tmp_mount_point)
{
    int i = 0;
    int ret = FS_MGR_DOMNT_FAILED;
    int mount_errors = 0;
    int first_mount_errno = 0;
    char *m;

    if (!fstab) {
        return ret;
    }

    for (i = 0; i < fstab->num_entries; i++) {
        if (!fs_match(fstab->recs[i].mount_point, n_name)) {
            continue;
        }

        /* We found our match */
        /* If this swap or a raw partition, report an error */
        if (!strcmp(fstab->recs[i].fs_type, "swap") ||
            !strcmp(fstab->recs[i].fs_type, "emmc") ||
            !strcmp(fstab->recs[i].fs_type, "mtd")) {
            ERROR("Cannot mount filesystem of type %s on %s\n",
                  fstab->recs[i].fs_type, n_blk_device);
            goto out;
        }

        /* First check the filesystem if requested */
        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
            wait_for_file(n_blk_device, WAIT_TIMEOUT);
        }

        if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
            check_fs(n_blk_device, fstab->recs[i].fs_type,
                     fstab->recs[i].mount_point);
        }

        if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
            !device_is_debuggable()) {
            if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
                ERROR("Could not set up verified partition, skipping!\n");
                continue;
            }
        }

        /* Now mount it where requested */
        if (tmp_mount_point) {
            m = tmp_mount_point;
        } else {
            m = fstab->recs[i].mount_point;
        }
        if (__mount(n_blk_device, m, &fstab->recs[i], FS_MGR_MNTALL_DEV_NOT_ENCRYPTED)) {
            if (!first_mount_errno) first_mount_errno = errno;
            mount_errors++;
            continue;
        } else {
            ret = 0;
            goto out;
        }
    }
    if (mount_errors) {
        ERROR("Cannot mount filesystem on %s at %s. error: %s\n",
            n_blk_device, m, strerror(first_mount_errno));
        if (first_mount_errno == EBUSY) {
            ret = FS_MGR_DOMNT_BUSY;
        } else {
            ret = FS_MGR_DOMNT_FAILED;
        }
    } else {
        /* We didn't find a match, say so and return an error */
        ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point);
    }

out:
    return ret;
}
Beispiel #12
0
/* When multiple fstab records share the same mount_point, it will
 * try to mount each one in turn, and ignore any duplicates after a
 * first successful mount.
 * Returns -1 on error, and  FS_MGR_MNTALL_* otherwise.
 */
int fs_mgr_mount_all(struct fstab *fstab)
{
    int i = 0;
    int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
    int error_count = 0;
    int mret = -1;
    int mount_errno = 0;
    int attempted_idx = -1;

    if (!fstab) {
        return -1;
    }

    for (i = 0; i < fstab->num_entries; i++) {
        /* Don't mount entries that are managed by vold */
        if (fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) {
            continue;
        }

        /* Skip swap and raw partition entries such as boot, recovery, etc */
        if (!strcmp(fstab->recs[i].fs_type, "swap") ||
            !strcmp(fstab->recs[i].fs_type, "emmc") ||
            !strcmp(fstab->recs[i].fs_type, "mtd")) {
            continue;
        }

		ERROR("[xiaolei] : blk device name %s\n", fstab->recs[i].blk_device);		
#ifdef MTK_UBIFS_SUPPORT
	if (!strcmp(fstab->recs[i].fs_type, "ubifs")) {
		char tmp[80];
		int n = ubi_attach_mtd(fstab->recs[i].blk_device + 5);
		if (n < 0) {
			return -1;
		}

		n = sprintf(tmp, "/dev/ubi%d_0", n);
		free(fstab->recs[i].blk_device);
		fstab->recs[i].blk_device = malloc(n+1);
		sprintf(fstab->recs[i].blk_device, "%s", tmp);
		ERROR("debug : ubifs blk_device %s", fstab->recs[i].blk_device);
	}
#endif
        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
            wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
        }

        if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
            !device_is_debuggable()) {
            if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
                ERROR("Could not set up verified partition, skipping!\n");
                continue;
            }
        }
        int last_idx_inspected;
        mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx, encryptable);
        i = last_idx_inspected;
        mount_errno = errno;

        /* Deal with encryptability. */
        if (!mret) {
            /* If this is encryptable, need to trigger encryption */
            if ((fstab->recs[attempted_idx].fs_mgr_flags & MF_FORCECRYPT)) {
                if (umount(fstab->recs[attempted_idx].mount_point) == 0) {
                    if (encryptable == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
                        ERROR("Will try to encrypt %s %s\n", fstab->recs[attempted_idx].mount_point,
                              fstab->recs[attempted_idx].fs_type);
                        encryptable = FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION;
                    } else {
                        ERROR("Only one encryptable/encrypted partition supported\n");
                        encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
                    }
                } else {
                    INFO("Could not umount %s - allow continue unencrypted\n",
                         fstab->recs[attempted_idx].mount_point);
                    continue;
                }
            }
            /* Success!  Go get the next one */
            continue;
        }

        /* mount(2) returned an error, check if it's encryptable and deal with it */
        if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
            fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
            if(partition_wiped(fstab->recs[attempted_idx].blk_device)) {
                ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__,
                      fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
                      fstab->recs[attempted_idx].fs_type);
                encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
                continue;
            } else {
                /* Need to mount a tmpfs at this mountpoint for now, and set
                 * properties that vold will query later for decrypting
                 */
                ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__,
                      fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
                      fstab->recs[attempted_idx].fs_type);
                if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
                    ++error_count;
                    continue;
                }
            }
            encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
        } else {
            ERROR("Failed to mount an un-encryptable or wiped partition on"
                   "%s at %s options: %s error: %s\n",
                   fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
                   fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
            ++error_count;
            continue;
        }
    }

    if (error_count) {
        return -1;
    } else {
        return encryptable;
    }
}
Beispiel #13
0
static int ubi_attach_mtd(const char *name)
{
    int ret;
    int mtd_num, ubi_num, vid_off;
    int ubi_ctrl, ubi_dev;
    int vols, avail_lebs, leb_size;
    char path[128];
    struct ubi_attach_req attach_req;
    struct ubi_mkvol_req mkvol_req;
    mtd_num = mtd_name_to_number(name);
    if (mtd_num == -1) {
        return -1;
    }

    for (ubi_num = 0; ubi_num < 4; ubi_num++)
    {
      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))
          return ubi_num;
      }
    }

    ubi_ctrl = open(UBI_CTRL_DEV, O_RDONLY);
    if (ubi_ctrl == -1) {
        return -1;
    }

    memset(&attach_req, 0, sizeof(struct ubi_attach_req));
    attach_req.ubi_num = UBI_DEV_NUM_AUTO;
    attach_req.mtd_num = mtd_num;
    attach_req.vid_hdr_offset = UBI_VID_OFFSET_AUTO;  

    ret = ioctl(ubi_ctrl, UBI_IOCATT, &attach_req);
    if (ret == -1) {
        close(ubi_ctrl);
        return -1;
    }

    ubi_num = attach_req.ubi_num;
   vid_off = attach_req.vid_hdr_offset;
    vols = ubi_dev_read_int(ubi_num, "volumes_count", -1);
    if (vols == 0) {
        sprintf(path, "/dev/ubi%d", ubi_num);
	ret = wait_for_file(path, 50);
        ubi_dev = open(path, O_RDONLY);
        if (ubi_dev == -1) {
            close(ubi_ctrl);
            return ubi_num;
        }
       
        avail_lebs = ubi_dev_read_int(ubi_num, "avail_eraseblocks", 0);
        leb_size = ubi_dev_read_int(ubi_num, "eraseblock_size", 0);
        memset(&mkvol_req, 0, sizeof(struct ubi_mkvol_req));
        mkvol_req.vol_id = UBI_VOL_NUM_AUTO;
        mkvol_req.alignment = 1;
        mkvol_req.bytes = (long long)avail_lebs * leb_size;
        mkvol_req.vol_type = UBI_DYNAMIC_VOLUME;
        ret = snprintf(mkvol_req.name, UBI_MAX_VOLUME_NAME + 1, "%s", name);
        mkvol_req.name_len = ret;
        ioctl(ubi_dev, UBI_IOCMKVOL, &mkvol_req);	
        close(ubi_dev);
    }

    close(ubi_ctrl);
    return ubi_num;
}
Beispiel #14
0
int main(int argc, char *argv[])
{
    int i, res;
    static char *const cmd[] = { "/init", NULL };
    struct fstab *fstab = NULL;

    for(i = 1; i < argc; ++i)
    {
        if(strcmp(argv[i], "-v") == 0)
        {
            printf("%d\n", VERSION_TRAMPOLINE);
            fflush(stdout);
            return 0;
        }
    }

    umask(000);

    // Init only the little we need, leave the rest for real init
    mkdir("/dev", 0755);
    mkdir("/dev/pts", 0755);
    mkdir("/dev/socket", 0755);
    mkdir("/proc", 0755);
    mkdir("/sys", 0755);

    mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
    mount("devpts", "/dev/pts", "devpts", 0, NULL);
    mount("proc", "/proc", "proc", 0, NULL);
    mount("sysfs", "/sys", "sysfs", 0, NULL);

    klog_init();
    ERROR("Running trampoline v%d\n", VERSION_TRAMPOLINE);

    if(is_charger_mode())
    {
        ERROR("Charger mode detected, skipping multirom\n");
        goto run_main_init;
    }

#if MR_DEVICE_HOOKS >= 3
    tramp_hook_before_device_init();
#endif

    ERROR("Initializing devices...");
    devices_init();
    ERROR("Done initializing");

    if(wait_for_file("/dev/graphics/fb0", 5) < 0)
    {
        ERROR("Waiting too long for fb0");
        goto exit;
    }

    fstab = fstab_auto_load();
    if(!fstab)
        goto exit;

#if 0 
    fstab_dump(fstab); //debug
#endif

    // mount and run multirom from sdcard
    mount_and_run(fstab);

exit:
    if(fstab)
        fstab_destroy(fstab);

    // close and destroy everything
    devices_close();

run_main_init:
    if(access(KEEP_REALDATA, F_OK) < 0)
    {
        umount(REALDATA);
        umount("/dev/pts");
        umount("/dev");
        rmdir("/dev/pts");
        rmdir("/dev/socket");
        rmdir("/dev");
        rmdir(REALDATA);
    }

    umount("/proc");
    umount("/sys");
    rmdir("/proc");
    rmdir("/sys");

    ERROR("Running main_init\n");

    fixup_symlinks();

    chmod("/main_init", EXEC_MASK);
    rename("/main_init", "/init");

    res = execve(cmd[0], cmd, NULL);
    ERROR("execve returned %d %d %s\n", res, errno, strerror(errno));
    return 0;
}
/* When multiple fstab records share the same mount_point, it will
 * try to mount each one in turn, and ignore any duplicates after a
 * first successful mount.
 * Returns -1 on error, and  FS_MGR_MNTALL_* otherwise.
 */
int fs_mgr_mount_all(struct fstab *fstab)
{
    int i = 0;
    int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
    int error_count = 0;
    int mret = -1;
    int mount_errno = 0;
    int attempted_idx = -1;

    if (!fstab) {
        return -1;
    }

    for (i = 0; i < fstab->num_entries; i++) {
        /* Don't mount entries that are managed by vold */
        if (fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) {
            continue;
        }

        /* Skip swap and raw partition entries such as boot, recovery, etc */
        if (!strcmp(fstab->recs[i].fs_type, "swap") ||
            !strcmp(fstab->recs[i].fs_type, "emmc") ||
            !strcmp(fstab->recs[i].fs_type, "mtd")) {
            continue;
        }

        /* Translate LABEL= file system labels into block devices */
        if (!strcmp(fstab->recs[i].fs_type, "ext2") ||
            !strcmp(fstab->recs[i].fs_type, "ext3") ||
            !strcmp(fstab->recs[i].fs_type, "ext4")) {
            int tret = translate_ext_labels(&fstab->recs[i]);
            if (tret < 0) {
                ERROR("Could not translate label to block device\n");
                continue;
            }
        }

        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
            wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
        }

        if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
            int rc = fs_mgr_setup_verity(&fstab->recs[i]);
            if (device_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
                INFO("Verity disabled");
            } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
                ERROR("Could not set up verified partition, skipping!\n");
                continue;
            }
        }
        int last_idx_inspected;
        mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
        i = last_idx_inspected;
        mount_errno = errno;

        /* Deal with encryptability. */
        if (!mret) {
            int status = handle_encryptable(fstab, &fstab->recs[attempted_idx]);

            if (status == FS_MGR_MNTALL_FAIL) {
                /* Fatal error - no point continuing */
                return status;
            }

            if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
                if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
                    // Log and continue
                    ERROR("Only one encryptable/encrypted partition supported\n");
                }
                encryptable = status;
            }

            /* Success!  Go get the next one */
            continue;
        }

        /* mount(2) returned an error, check if it's encryptable and deal with it */
        if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
            fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
            if(partition_wiped(fstab->recs[attempted_idx].blk_device)) {
                ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__,
                      fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
                      fstab->recs[attempted_idx].fs_type);
                encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
                continue;
            } else {
                /* Need to mount a tmpfs at this mountpoint for now, and set
                 * properties that vold will query later for decrypting
                 */
                ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__,
                      fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
                      fstab->recs[attempted_idx].fs_type);
                if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
                    ++error_count;
                    continue;
                }
            }
            encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
        } else {
            ERROR("Failed to mount an un-encryptable or wiped partition on"
                   "%s at %s options: %s error: %s\n",
                   fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
                   fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
            ++error_count;
            continue;
        }
    }

    if (error_count) {
        return -1;
    } else {
        return encryptable;
    }
}
int main(int argc, char **argv)
{
    struct fstab *fstab;
    int ret=0, syspart, i, status;
    char filenamePatched[PATH_MAX], filenameSystem[PATH_MAX];

    // check arguments
    if(argc!=2) {
        ERROR("Invalid Arguments");
        return -EINVAL;
    }

    // get syspart from cmdline
    syspart = getDualbootSyspart();
    if(syspart<0) {
        ERROR("Cannot read system number");
        return -EINVAL;
    }

    // patch fstab
    sprintf(filenamePatched, "%s.patched", argv[1]);
    sprintf(filenameSystem, "%s.system", argv[1]);
    patch_fstab(argv[1], filenamePatched, filenameSystem, syspart);

    // mount system
    fstab = fs_mgr_read_fstab(filenameSystem);
    ret = fs_mgr_mount_all(fstab);
    fs_mgr_free_fstab(fstab);
    if (ret == -1) {
        ERROR("fs_mgr_mount_all returned an error\n");
    }

    // mount data
    fstab = fs_mgr_read_fstab(argv[1]);
    for (i = 0; i < fstab->num_entries; ++i) {
        struct fstab_rec* v = &fstab->recs[i];
        
        if(strcmp(PARTITION_USERDATA, v->blk_device))
            continue;

        if (v->fs_mgr_flags & MF_WAIT) {
            wait_for_file(v->blk_device, WAIT_TIMEOUT);
        }

        if (v->fs_mgr_flags & MF_CHECK) {
            check_fs(v->blk_device, v->fs_type, v->mount_point);
        }

        if(mountScriptExists()) {
            char *e2fsck_argv[] = {
                "/system/bin/mount_ext4.sh",
                v->blk_device,
                v->mount_point
            };
            ret = android_fork_execvp_ext(ARRAY_SIZE(e2fsck_argv), e2fsck_argv, &status, true, LOG_KLOG, true, NULL);
        }
        else {
            ret = mount(v->blk_device, v->mount_point,  v->fs_type, v->flags, v->fs_options);
        }
    }
    fs_mgr_free_fstab(fstab);
    if (ret == -1) {
        ERROR("error mounting userdata\n");
    }
    
    return ret;
}
Beispiel #17
0
/* mount <type> <device> <path> <flags ...> <options> */
int do_mount(int nargs, char **args)
{
    char tmp[64];
    char *source, *target, *system;
    char *options = NULL;
    unsigned flags = 0;
    int n, i;
    int wait = 0;

    for (n = 4; n < nargs; n++) {
        for (i = 0; mount_flags[i].name; i++) {
            if (!strcmp(args[n], mount_flags[i].name)) {
                flags |= mount_flags[i].flag;
                break;
            }
        }

        if (!mount_flags[i].name) {
            if (!strcmp(args[n], "wait"))
                wait = 1;
            /* if our last argument isn't a flag, wolf it up as an option string */
            else if (n + 1 == nargs)
                options = args[n];
        }
    }

    system = args[1];
    source = args[2];
    target = args[3];

    if (!strncmp(source, "mtd@", 4)) {
        n = mtd_name_to_number(source + 4);
        if (n < 0) {
            return -1;
        }

        sprintf(tmp, "/dev/block/mtdblock%d", n);

        if (wait)
            wait_for_file(tmp, COMMAND_RETRY_TIMEOUT);
        if (mount(tmp, target, system, flags, options) < 0) {
            return -1;
        }

        goto exit_success;
    } else if (!strncmp(source, "loop@", 5)) {
        int mode, loop, fd;
        struct loop_info info;

        mode = (flags & MS_RDONLY) ? O_RDONLY : O_RDWR;
        fd = open(source + 5, mode);
        if (fd < 0) {
            return -1;
        }

        for (n = 0; ; n++) {
            sprintf(tmp, "/dev/block/loop%d", n);
            loop = open(tmp, mode);
            if (loop < 0) {
                return -1;
            }

            /* if it is a blank loop device */
            if (ioctl(loop, LOOP_GET_STATUS, &info) < 0 && errno == ENXIO) {
                /* if it becomes our loop device */
                if (ioctl(loop, LOOP_SET_FD, fd) >= 0) {
                    close(fd);

                    if (mount(tmp, target, system, flags, options) < 0) {
                        ioctl(loop, LOOP_CLR_FD, 0);
                        close(loop);
                        return -1;
                    }

                    close(loop);
                    goto exit_success;
                }
            }

            close(loop);
        }

        close(fd);
        ERROR("out of loopback devices");
        return -1;
    } else {
        if (wait)
            wait_for_file(source, COMMAND_RETRY_TIMEOUT);
        if (mount(source, target, system, flags, options) < 0) {
            /* If this fails, it may be an encrypted filesystem
             * or it could just be wiped.  If wiped, that will be
             * handled later in the boot process.
             * We only support encrypting /data.  Check
             * if we're trying to mount it, and if so,
             * assume it's encrypted, mount a tmpfs instead.
             * Then save the orig mount parms in properties
             * for vold to query when it mounts the real
             * encrypted /data.
             */
            if (!strcmp(target, DATA_MNT_POINT) && !partition_wiped(source)) {
                const char *tmpfs_options;

                tmpfs_options = property_get("ro.crypto.tmpfs_options");

                if (mount("tmpfs", target, "tmpfs", MS_NOATIME | MS_NOSUID | MS_NODEV,
                    tmpfs_options) < 0) {
                    return -1;
                }

                /* Set the property that triggers the framework to do a minimal
                 * startup and ask the user for a password
                 */
                property_set("ro.crypto.state", "encrypted");
                property_set("vold.decrypt", "1");
            } else {
                return -1;
            }
        }

        if (!strcmp(target, DATA_MNT_POINT)) {
            char fs_flags[32];

            /* Save the original mount options */
            property_set("ro.crypto.fs_type", system);
            property_set("ro.crypto.fs_real_blkdev", source);
            property_set("ro.crypto.fs_mnt_point", target);
            if (options) {
                property_set("ro.crypto.fs_options", options);
            }
            snprintf(fs_flags, sizeof(fs_flags), "0x%8.8x", flags);
            property_set("ro.crypto.fs_flags", fs_flags);
        }
    }

exit_success:
    /* If not running encrypted, then set the property saying we are
     * unencrypted, and also trigger the action for a nonencrypted system.
     */
    if (!strcmp(target, DATA_MNT_POINT)) {
        const char *prop;

        prop = property_get("ro.crypto.state");
        if (! prop) {
            prop = "notset";
        }
        if (strcmp(prop, "encrypted")) {
            property_set("ro.crypto.state", "unencrypted");
            action_for_each_trigger("nonencrypted", action_add_queue_tail);
        }
    }

    return 0;

}
Beispiel #18
0
/* mount <type> <device> <path> <flags ...> <options> */
int do_mount(int nargs, char **args)
{
    char tmp[64];
    char *source, *target, *type;
    char *options = NULL;
    unsigned flags = 0;
    int n, i;
    int wait = 0;
    //add for power loss test
    struct stat stbuf; 

    for (n = 4; n < nargs; n++) {
        for (i = 0; mount_flags[i].name; i++) {
            if (!strcmp(args[n], mount_flags[i].name)) {
                flags |= mount_flags[i].flag;
                break;
            }
        }

        if (!mount_flags[i].name) {
            if (!strcmp(args[n], "wait"))
                wait = 1;
            /* if our last argument isn't a flag, wolf it up as an option string */
            else if (n + 1 == nargs)
                options = args[n];
        }
    }

    type = args[1];
    source = args[2];
    target = args[3];

    if (!strncmp(source, "mtd@", 4)) {
        n = mtd_name_to_number(source + 4);
        if (n < 0) {
            return -1;
        }

        sprintf(tmp, "/dev/block/mtdblock%d", n);

        if (wait)
            wait_for_file(tmp, COMMAND_RETRY_TIMEOUT);
        if (mount(tmp, target, type, flags, options) < 0) {
            return -1;
        }

        goto exit_success;
    } else if (!strncmp(source, "loop@", 5)) {
        int mode, loop, fd;
        struct loop_info info;

        mode = (flags & MS_RDONLY) ? O_RDONLY : O_RDWR;
        fd = open(source + 5, mode);
        if (fd < 0) {
            return -1;
        }

        for (n = 0; ; n++) {
            sprintf(tmp, "/dev/block/loop%d", n);
            loop = open(tmp, mode);
            if (loop < 0) {
                return -1;
            }

            /* if it is a blank loop device */
            if (ioctl(loop, LOOP_GET_STATUS, &info) < 0 && errno == ENXIO) {
                /* if it becomes our loop device */
                if (ioctl(loop, LOOP_SET_FD, fd) >= 0) {
                    close(fd);

                    if (mount(tmp, target, type, flags, options) < 0) {
                        ioctl(loop, LOOP_CLR_FD, 0);
                        close(loop);
                        return -1;
                    }

                    close(loop);
                    goto exit_success;
                }
            }

            close(loop);
        }

        close(fd);
        ERROR("out of loopback devices");
        return -1;
    } else {

#ifdef MTK_EMMC_SUPPORT
         struct phone_encrypt_state ps;  
         if (!strcmp(target, DATA_MNT_POINT)) {
             if (misc_get_phone_encrypt_state(&ps) < 0) {
                 printf("Failed to get encrypted status in MISC\n");
             }
             else {
                 printf("Success: get encrypted status: 0x%x in MISC\n", ps.state);
             }  
         }
#endif

        if (wait)
            wait_for_file(source, COMMAND_RETRY_TIMEOUT);
        if (mount(source, target, type, flags, options) < 0) {
            /* If this fails, it may be an encrypted filesystem
             * or it could just be wiped.  If wiped, that will be
             * handled later in the boot process.
             * We only support encrypting /data.  Check
             * if we're trying to mount it, and if so,
             * assume it's encrypted, mount a tmpfs instead.
             * Then save the orig mount parms in properties
             * for vold to query when it mounts the real
             * encrypted /data.
             */


            if (!strcmp(target, DATA_MNT_POINT)) {
                int fd;
                if ((fd = open(source, O_RDONLY)) < 0) {
                     printf("Mount /data fail because source(%s) doesn't exist.", source);
                     return -1;
                }
            }

            if (!strcmp(target, DATA_MNT_POINT) && !partition_wiped(source)) {
                const char *tmpfs_options;

                tmpfs_options = property_get("ro.crypto.tmpfs_options");

                if (mount("tmpfs", target, "tmpfs", MS_NOATIME | MS_NOSUID | MS_NODEV,
                    tmpfs_options) < 0) {
                    return -1;
                }

                /* Set the property that triggers the framework to do a minimal
                 * startup and ask the user for a password
                 */
                property_set("ro.crypto.state", "encrypted");
                property_set("vold.decrypt", "1");
            } else {
                return -1;
            }
        }
#ifdef MTK_EMMC_SUPPORT
        else {
             if (!strcmp(target, DATA_MNT_POINT)) {
                    if (ps.state == PHONE_ENCRYPTED) {
                        ps.state = PHONE_UNCRYPTED;
                        if (misc_set_phone_encrypt_state(&ps) < 0) {
                            printf("Failed to set encrypted status to 0x%x in MISC\n", ps.state);
                        }
                        else {
                            printf("Success: Set encrypted status to 0x%x in MISC\n", ps.state);
                        }
                    }
             }
        }
#endif

        if (!strcmp(target, DATA_MNT_POINT)) {
            char fs_flags[32];

            /* Save the original mount options */
            property_set("ro.crypto.fs_type", type);
            property_set("ro.crypto.fs_real_blkdev", source);
            property_set("ro.crypto.fs_mnt_point", target);
            if (options) {
                property_set("ro.crypto.fs_options", options);
            }
            snprintf(fs_flags, sizeof(fs_flags), "0x%8.8x", flags);
            property_set("ro.crypto.fs_flags", fs_flags);
        }
        if (!strncmp(type, "ext4", 4)){
            if (!strncmp(target, "/data", 5)){
               printf("delete lost-found in data dir\n");
               system("/system/bin/rm -r /data/lost+found/*");
               
               if (stat("/data/data", &stbuf) < 0){
                   printf("stat syscall fail\n");
               }
               if (S_ISREG(stbuf.st_mode)){
                   printf("delete /data/data file\n");
                   system("/system/bin/rm -r /data/data");    
               }

               if (stat("/data/system", &stbuf) < 0){
                   printf("stat syscall fail\n");
               }
               if (S_ISREG(stbuf.st_mode)){
                   printf("delete /data/system file\n");
                   system("/system/bin/rm -r /data/system");    
               }

               if (stat("/data/misc", &stbuf) < 0){
                   printf("stat syscall fail\n");
               }
               if (S_ISREG(stbuf.st_mode)){
                   printf("delete /data/misc file\n");
                   system("/system/bin/rm -r /data/misc");    
               }

               if (stat("/data/local", &stbuf) < 0){
                   printf("stat syscall fail\n");
               }
               if (S_ISREG(stbuf.st_mode)){
                   printf("delete /data/local file\n");
                   system("/system/bin/rm -r /data/local");    
               }

               if (stat("/data/app-private", &stbuf) < 0){
                   printf("stat syscall fail\n");
               }
               if (S_ISREG(stbuf.st_mode)){
                   printf("delete /data/app-private file\n");
                   system("/system/bin/rm -r /data/app-private");    
               }

               if (stat("/data/dalvik-cache", &stbuf) < 0){
                   printf("stat syscall fail\n");
               }
               if (S_ISREG(stbuf.st_mode)){
                   printf("delete /data/dalvik-cache file\n");
                   system("/system/bin/rm -r /data/dalvik-cache");    
               }


               if (stat("/data/property", &stbuf) < 0){
                   printf("stat syscall fail\n");
               }
               if (S_ISREG(stbuf.st_mode)){
                   printf("delete /data/property file\n");
                   system("/system/bin/rm -r /data/property");    
               } 

               if (stat("/data/mvg_root", &stbuf) < 0){
                   printf("stat syscall fail\n");
               }
               if (S_ISREG(stbuf.st_mode)){
                   printf("delete /data/mvg_root file\n");
                   system("/system/bin/rm -r /data/mvg_root");    
               }

               if (stat("/data/anr", &stbuf) < 0){
                   printf("stat syscall fail\n");
               }
               if (S_ISREG(stbuf.st_mode)){
                   printf("delete /data/anr file\n");
                   system("/system/bin/rm -r /data/anr");    
               }

               if (stat("/data/app", &stbuf) < 0){
                   printf("stat syscall fail\n");
               }
               if (S_ISREG(stbuf.st_mode)){
                   printf("delete /data/app file\n");
                   system("/system/bin/rm -r /data/app");    
               }

               if (stat("/data/nvram", &stbuf) < 0){
                   printf("stat syscall fail\n");
               }
               if (S_ISREG(stbuf.st_mode)){
                   printf("delete /data/nvram file\n");
                   system("/system/bin/rm -r /data/nvram");    
               }

               if (stat("/data/secure", &stbuf) < 0){
                   printf("stat syscall fail\n");
               }
               if (S_ISREG(stbuf.st_mode)){
                   printf("delete /data/secure file\n");
                   system("/system/bin/rm -r /data/secure");    
               }
            }

            if (!strncmp(target, "/cache", 6)){
               printf("delete lost-found in cache dir\n");
               system("/system/bin/rm -r /cache/lost+found/*");
            }
        }        
    }

exit_success:
    /* If not running encrypted, then set the property saying we are
     * unencrypted, and also trigger the action for a nonencrypted system.
     */
    if (!strcmp(target, DATA_MNT_POINT)) {
        const char *prop;

        prop = property_get("ro.crypto.state");
        if (! prop) {
            prop = "notset";
        }
        if (strcmp(prop, "encrypted")) {
            property_set("ro.crypto.state", "unencrypted");
            action_for_each_trigger("nonencrypted", action_add_queue_tail);
        }
    }

    return 0;

}
Beispiel #19
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;
}
int fs_mgr_mount_all(struct fstab *fstab)
{
    int i = 0;
    int encrypted = 0;
    int ret = -1;
    int mret;

    if (!fstab) {
        return ret;
    }

    for (i = 0; i < fstab->num_entries; i++) {
        /* Don't mount entries that are managed by vold */
        if (fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) {
            continue;
        }

        /* Skip raw partition entries such as boot, recovery, etc */
        if (!strcmp(fstab->recs[i].fs_type, "emmc") ||
            !strcmp(fstab->recs[i].fs_type, "mtd")) {
            continue;
        }

        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
            wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
        }

        if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
            check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
                     fstab->recs[i].mount_point);
        }

        mret = mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point,
                     fstab->recs[i].fs_type, fstab->recs[i].flags,
                     fstab->recs[i].fs_options);
        if (!mret) {
            /* Success!  Go get the next one */
            continue;
        }

        /* mount(2) returned an error, check if it's encrypted and deal with it */
        if ((fstab->recs[i].fs_mgr_flags & MF_CRYPT) &&
            !partition_wiped(fstab->recs[i].blk_device)) {
            /* Need to mount a tmpfs at this mountpoint for now, and set
             * properties that vold will query later for decrypting
             */
            if (mount("tmpfs", fstab->recs[i].mount_point, "tmpfs",
                  MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS) < 0) {
                ERROR("Cannot mount tmpfs filesystem for encrypted fs at %s\n",
                        fstab->recs[i].mount_point);
                goto out;
            }
            encrypted = 1;
        } else {
            ERROR("Cannot mount filesystem on %s at %s\n",
                    fstab->recs[i].blk_device, fstab->recs[i].mount_point);
            goto out;
        }
    }

    if (encrypted) {
        ret = 1;
    } else {
        ret = 0;
    }

out:
    return ret;
}
Beispiel #21
0
/* If tmp_mount_point is non-null, mount the filesystem there.  This is for the
 * tmp mount we do to check the user password
 * If multiple fstab entries are to be mounted on "n_name", it will try to mount each one
 * in turn, and stop on 1st success, or no more match.
 */
int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
                    char *tmp_mount_point)
{
    int i = 0;
    int ret = FS_MGR_DOMNT_FAILED;
    int mount_errors = 0;
    int first_mount_errno = 0;
    char *m;

    if (!fstab) {
        return ret;
    }

    for (i = 0; i < fstab->num_entries; i++) {
        if (!fs_match(fstab->recs[i].mount_point, n_name)) {
            continue;
        }

        /* We found our match */
        /* If this swap or a raw partition, report an error */
        if (!strcmp(fstab->recs[i].fs_type, "swap") ||
            !strcmp(fstab->recs[i].fs_type, "emmc") ||
            !strcmp(fstab->recs[i].fs_type, "mtd")) {
            ERROR("Cannot mount filesystem of type %s on %s\n",
                  fstab->recs[i].fs_type, n_blk_device);
            goto out;
        }

        /* First check the filesystem if requested */
        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
            wait_for_file(n_blk_device, WAIT_TIMEOUT);
        }

        int force_check = do_quota(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
                                   &fstab->recs[i]);

        if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) {
            check_fs(n_blk_device, fstab->recs[i].fs_type,
                     fstab->recs[i].mount_point);
        }

        if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
            do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i]);
        }

        if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
            int rc = fs_mgr_setup_verity(&fstab->recs[i]);
            if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
                INFO("Verity disabled");
            } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
                ERROR("Could not set up verified partition, skipping!\n");
                continue;
            }
        }

        /* Now mount it where requested */
        if (tmp_mount_point) {
            m = tmp_mount_point;
        } else {
            m = fstab->recs[i].mount_point;
        }
        if (__mount(n_blk_device, m, &fstab->recs[i])) {
            if (!first_mount_errno) first_mount_errno = errno;
            mount_errors++;
            continue;
        } else {
            ret = 0;
            goto out;
        }
    }
    if (mount_errors) {
        ERROR("Cannot mount filesystem on %s at %s. error: %s\n",
            n_blk_device, m, strerror(first_mount_errno));
        if (first_mount_errno == EBUSY) {
            ret = FS_MGR_DOMNT_BUSY;
        } else {
            ret = FS_MGR_DOMNT_FAILED;
        }
    } else {
        /* We didn't find a match, say so and return an error */
        ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point);
    }

out:
    return ret;
}
Beispiel #22
0
/* When multiple fstab records share the same mount_point, it will
 * try to mount each one in turn, and ignore any duplicates after a
 * first successful mount.
 * Returns -1 on error, and  FS_MGR_MNTALL_* otherwise.
 */
int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
{
    int i = 0;
    int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
    int error_count = 0;
    int mret = -1;
    int mount_errno = 0;
    int attempted_idx = -1;

    if (!fstab) {
        return -1;
    }

    for (i = 0; i < fstab->num_entries; i++) {
        /* Don't mount entries that are managed by vold or not for the mount mode*/
        if ((fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) ||
             ((mount_mode == MOUNT_MODE_LATE) && !fs_mgr_is_latemount(&fstab->recs[i])) ||
             ((mount_mode == MOUNT_MODE_EARLY) && fs_mgr_is_latemount(&fstab->recs[i]))) {
            continue;
        }

        /* Skip swap and raw partition entries such as boot, recovery, etc */
        if (!strcmp(fstab->recs[i].fs_type, "swap") ||
            !strcmp(fstab->recs[i].fs_type, "emmc") ||
            !strcmp(fstab->recs[i].fs_type, "mtd")) {
            continue;
        }

        /* Skip mounting the root partition, as it will already have been mounted */
        if (!strcmp(fstab->recs[i].mount_point, "/")) {
            if ((fstab->recs[i].fs_mgr_flags & MS_RDONLY) != 0) {
                fs_mgr_set_blk_ro(fstab->recs[i].blk_device);
            }
            continue;
        }

        /* Translate LABEL= file system labels into block devices */
        if (!strcmp(fstab->recs[i].fs_type, "ext2") ||
            !strcmp(fstab->recs[i].fs_type, "ext3") ||
            !strcmp(fstab->recs[i].fs_type, "ext4")) {
            int tret = translate_ext_labels(&fstab->recs[i]);
            if (tret < 0) {
                ERROR("Could not translate label to block device\n");
                continue;
            }
        }

        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
            wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
        }

        if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
            int rc = fs_mgr_setup_verity(&fstab->recs[i]);
            if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
                INFO("Verity disabled");
            } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
                ERROR("Could not set up verified partition, skipping!\n");
                continue;
            }
        }
        int last_idx_inspected;
        int top_idx = i;

        mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
        i = last_idx_inspected;
        mount_errno = errno;

        /* Deal with encryptability. */
        if (!mret) {
            int status = handle_encryptable(&fstab->recs[attempted_idx]);

            if (status == FS_MGR_MNTALL_FAIL) {
                /* Fatal error - no point continuing */
                return status;
            }

            if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
                if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
                    // Log and continue
                    ERROR("Only one encryptable/encrypted partition supported\n");
                }
                encryptable = status;
            }

            /* Success!  Go get the next one */
            continue;
        }

        /* mount(2) returned an error, handle the encryptable/formattable case */
        bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
        bool crypt_footer = false;
        if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
            fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) {
            /* top_idx and attempted_idx point at the same partition, but sometimes
             * at two different lines in the fstab.  Use the top one for formatting
             * as that is the preferred one.
             */
            ERROR("%s(): %s is wiped and %s %s is formattable. Format it.\n", __func__,
                  fstab->recs[top_idx].blk_device, fstab->recs[top_idx].mount_point,
                  fstab->recs[top_idx].fs_type);
            if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
                strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
                int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY);
                if (fd >= 0) {
                    INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc);
                    wipe_block_device(fd, get_file_size(fd));
                    close(fd);
                } else {
                    ERROR("%s(): %s wouldn't open (%s)\n", __func__,
                          fstab->recs[top_idx].key_loc, strerror(errno));
                }
            } else if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
                !strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
                crypt_footer = true;
            }
            if (fs_mgr_do_format(&fstab->recs[top_idx], crypt_footer) == 0) {
                /* Let's replay the mount actions. */
                i = top_idx - 1;
                continue;
            } else {
                ERROR("%s(): Format failed. Suggest recovery...\n", __func__);
                encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
                continue;
            }
        }
        if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
            fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
            if (wiped) {
                ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__,
                      fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
                      fstab->recs[attempted_idx].fs_type);
                encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
                continue;
            } else {
                /* Need to mount a tmpfs at this mountpoint for now, and set
                 * properties that vold will query later for decrypting
                 */
                ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__,
                      fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
                      fstab->recs[attempted_idx].fs_type);
                if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
                    ++error_count;
                    continue;
                }
            }
            encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
        } else {
            if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) {
                ERROR("Ignoring failure to mount an un-encryptable or wiped partition on"
                       "%s at %s options: %s error: %s\n",
                       fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
                       fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
            } else {
                ERROR("Failed to mount an un-encryptable or wiped partition on"
                       "%s at %s options: %s error: %s\n",
                       fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
                       fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
                ++error_count;
            }
            continue;
        }
    }

    if (error_count) {
        return -1;
    } else {
        return encryptable;
    }
}
Beispiel #23
0
/* This must be called after mount_all, because the mkswap command needs to be
 * available.
 */
int fs_mgr_swapon_all(struct fstab *fstab)
{
    int i = 0;
    int flags = 0;
    int err = 0;
    int ret = 0;
    int status;
    char *mkswap_argv[2] = {
        MKSWAP_BIN,
        NULL
    };

    if (!fstab) {
        return -1;
    }

    for (i = 0; i < fstab->num_entries; i++) {
        /* Skip non-swap entries */
        if (strcmp(fstab->recs[i].fs_type, "swap")) {
            continue;
        }

        if (fstab->recs[i].zram_size > 0) {
            /* A zram_size was specified, so we need to configure the
             * device.  There is no point in having multiple zram devices
             * on a system (all the memory comes from the same pool) so
             * we can assume the device number is 0.
             */
            FILE *zram_fp;

            zram_fp = fopen(ZRAM_CONF_DEV, "r+");
            if (zram_fp == NULL) {
                ERROR("Unable to open zram conf device %s\n", ZRAM_CONF_DEV);
                ret = -1;
                continue;
            }
            fprintf(zram_fp, "%d\n", fstab->recs[i].zram_size);
            fclose(zram_fp);
        }

        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
            wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
        }

        /* Initialize the swap area */
        mkswap_argv[1] = fstab->recs[i].blk_device;
        err = android_fork_execvp_ext(ARRAY_SIZE(mkswap_argv), mkswap_argv,
                                      &status, true, LOG_KLOG, false, NULL);
        if (err) {
            ERROR("mkswap failed for %s\n", fstab->recs[i].blk_device);
            ret = -1;
            continue;
        }

        /* If -1, then no priority was specified in fstab, so don't set
         * SWAP_FLAG_PREFER or encode the priority */
        if (fstab->recs[i].swap_prio >= 0) {
            flags = (fstab->recs[i].swap_prio << SWAP_FLAG_PRIO_SHIFT) &
                    SWAP_FLAG_PRIO_MASK;
            flags |= SWAP_FLAG_PREFER;
        } else {
            flags = 0;
        }
        err = swapon(fstab->recs[i].blk_device, flags);
        if (err) {
            ERROR("swapon failed for %s\n", fstab->recs[i].blk_device);
            ret = -1;
        }
    }

    return ret;
}
Beispiel #24
0
int ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
  int status = 0;

  try {
    ACE_DEBUG((LM_INFO,"(%P|%t) %T subscriber main\n"));

    ::DDS::DomainParticipantFactory_var dpf = TheParticipantFactoryWithArgs(argc, argv);

    //      TheServiceParticipant->liveliness_factor(100);

    // let the Service_Participant (in above line) strip out -DCPSxxx parameters
    // and then get application specific parameters.
    parse_args(argc, argv);

    if (!topics) {
      ACE_ERROR((LM_ERROR,
                 ACE_TEXT("(%P|%t) Must run with one or more of the following: -s1 -s2 -s3 -s4 -s5 -p6 -p7\n")));
      return 1;
    }

    ::T1::Foo1TypeSupport_var fts1;
    ::T4::Foo4TypeSupport_var fts4;

    if (topics & (TOPIC_T1 | TOPIC_T3 | TOPIC_T4| TOPIC_T5)) {
      fts1 = new ::T1::Foo1TypeSupportImpl;
    }

    if (topics & TOPIC_T2) {
      fts4 = new ::T4::Foo4TypeSupportImpl;
    }

    ::DDS::DomainParticipant_var dp =
        dpf->create_participant(MY_DOMAIN,
                                PARTICIPANT_QOS_DEFAULT,
                                ::DDS::DomainParticipantListener::_nil(),
                                ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);

    if (CORBA::is_nil(dp)) {
      ACE_ERROR((LM_ERROR,
                 ACE_TEXT("(%P|%t) create_participant failed.\n")));
      return 1;
    }

    if (topics & (TOPIC_T1 | TOPIC_T3 | TOPIC_T4 | TOPIC_T5)) {
      if (::DDS::RETCODE_OK != fts1->register_type(dp, MY_TYPE1)) {
        ACE_ERROR((LM_ERROR,
                   ACE_TEXT("Failed to register the Foo1TypeSupport.")));
        return 1;
      }
    }

    if (topics & TOPIC_T2) {
      if (::DDS::RETCODE_OK != fts4->register_type(dp, MY_TYPE4)) {
        ACE_ERROR((LM_ERROR,
                   ACE_TEXT("Failed to register the Foo4TypeSupport.")));
        return 1;
      }
    }

    ::DDS::Topic_var topic1;
    ::DDS::Topic_var topic2;
    ::DDS::Topic_var topic3;
    ::DDS::Topic_var topic4;
    ::DDS::Topic_var topic5;
    ::DDS::Topic_var topic6;
    ::DDS::Topic_var topic7;

    if (topics & TOPIC_T1) {
      topic1 = dp->create_topic(MY_TOPIC1, MY_TYPE1, TOPIC_QOS_DEFAULT,
                                ::DDS::TopicListener::_nil(),
                                ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
      if (CORBA::is_nil(topic1)) {
        return 1;
      }
    }

    if (topics & TOPIC_T2) {
      topic2 = dp->create_topic(MY_TOPIC2, MY_TYPE4, TOPIC_QOS_DEFAULT,
                                ::DDS::TopicListener::_nil(),
                                ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
      if (CORBA::is_nil(topic2)) {
        return 1;
      }
    }

    if (topics & TOPIC_T3) {
      topic3 = dp->create_topic(MY_TOPIC3, MY_TYPE1, TOPIC_QOS_DEFAULT,
                                ::DDS::TopicListener::_nil(),
                                ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
      if (CORBA::is_nil(topic3)) {
        return 1;
      }
    }

    if (topics & TOPIC_T4) {
      topic4 = dp->create_topic(MY_TOPIC4, MY_TYPE1, TOPIC_QOS_DEFAULT,
                                ::DDS::TopicListener::_nil(),
                                ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
      if (CORBA::is_nil(topic4)) {
        return 1;
      }
    }

    if (topics & TOPIC_T5) {
      topic5 = dp->create_topic(MY_TOPIC5, MY_TYPE1, TOPIC_QOS_DEFAULT,
                                ::DDS::TopicListener::_nil(),
                                ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
      if (CORBA::is_nil(topic5)) {
        return 1;
      }
    }

    if (publish_topics & TOPIC_T6) {
      topic6 = dp->create_topic(MY_TOPIC6, MY_TYPE1, TOPIC_QOS_DEFAULT,
                                ::DDS::TopicListener::_nil(),
                                ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
      if (CORBA::is_nil(topic6)) {
        return 1;
      }
    }

    if (publish_topics & TOPIC_T7) {
      topic7 = dp->create_topic(MY_TOPIC7, MY_TYPE1, TOPIC_QOS_DEFAULT,
                                ::DDS::TopicListener::_nil(),
                                ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
      if (CORBA::is_nil(topic7)) {
        return 1;
      }
    }

    ////////////////////////////////////////////////////////////////////////////
    // Create the publisher and datawriter
    ////////////////////////////////////////////////////////////////////////////
    ::DDS::Publisher_var pub =
      dp->create_publisher(PUBLISHER_QOS_DEFAULT,
                           ::DDS::PublisherListener::_nil(),
                           ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
    if (CORBA::is_nil(pub)) {
      ACE_ERROR_RETURN((LM_ERROR,
                        ACE_TEXT("(%P|%t) create_publisher failed.\n")),
                       1);
    }

    ::DDS::DataWriterQos dw_qos;
    pub->get_default_datawriter_qos(dw_qos);

    dw_qos.resource_limits.max_samples_per_instance = max_samples_per_instance;

    dw_qos.liveliness.lease_duration.sec = LEASE_DURATION_SEC;
    dw_qos.liveliness.lease_duration.nanosec = 0;

    int num_writers(0);

    ::DDS::DataWriter_var dw1;
    ::DDS::DataWriter_var dw2;

    if (publish_topics & TOPIC_T6) {
      dw1 = pub->create_datawriter(topic6, dw_qos,
                                  ::DDS::DataWriterListener::_nil(),
                                  ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
      if (CORBA::is_nil(dw1)) {
        ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) create_datawriter failed.\n")));
        return 1;
      }
      ++num_writers;
    }

    if (publish_topics & TOPIC_T7) {
      dw2 = pub->create_datawriter(topic7, dw_qos,
                                   ::DDS::DataWriterListener::_nil(),
                                   ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
      if (CORBA::is_nil(dw2)) {
        ACE_ERROR((LM_ERROR, ACE_TEXT("(%P|%t) create_datawriter failed.\n")));
        return 1;
      }
      ++num_writers;
    }

    Writer** writers = new Writer*[num_writers];

    int idx(0);

    if (publish_topics & TOPIC_T6) {
      writers[idx++] = new Writer(dw1, 1, num_ops_per_thread);
    }

    if (publish_topics & TOPIC_T7) {
      writers[idx++] = new Writer(dw2, 1, num_ops_per_thread);
    }

    for (int i = 0; i < num_writers; ++i) {
      writers[i]->start();
    }


    ////////////////////////////////////////////////////////////////////////////
    // Create the subscriber
    ////////////////////////////////////////////////////////////////////////////
    ::DDS::Subscriber_var sub =
        dp->create_subscriber(SUBSCRIBER_QOS_DEFAULT,
                              ::DDS::SubscriberListener::_nil(),
                              ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
    if (CORBA::is_nil(sub)) {
      ACE_ERROR_RETURN((LM_ERROR,
                        ACE_TEXT("(%P|%t) create_subscriber failed.\n")),
                       1);
    }

    // Create the Datareaders
    ::DDS::DataReaderQos dr_qos;
    sub->get_default_datareader_qos(dr_qos);

    dr_qos.resource_limits.max_samples_per_instance = max_samples_per_instance;

    dr_qos.liveliness.lease_duration.sec = LEASE_DURATION_SEC;
    dr_qos.liveliness.lease_duration.nanosec = 0;

    dr_qos.reliability.kind = DDS::RELIABLE_RELIABILITY_QOS;

    ::DDS::DataReader_var dr1;
    ::DDS::DataReader_var dr2_1;
    ::DDS::DataReader_var dr2_2;
    ::DDS::DataReader_var dr2_3;
    ::DDS::DataReader_var dr3;
    ::DDS::DataReader_var dr4;
    ::DDS::DataReader_var dr5;

    ::DDS::DataReaderListener_var drl1 =
        new DataReaderListenerImpl1(num_ops_per_thread);
    ::DDS::DataReaderListener_var drl2_1 =
        new DataReaderListenerImpl4(num_ops_per_thread);
    ::DDS::DataReaderListener_var drl2_2 =
        new DataReaderListenerImpl4(num_ops_per_thread);
    ::DDS::DataReaderListener_var drl2_3 =
        new DataReaderListenerImpl4(num_ops_per_thread);
    ::DDS::DataReaderListener_var drl3 =
        new DataReaderListenerImpl1(num_ops_per_thread);
    ::DDS::DataReaderListener_var drl4 =
        new DataReaderListenerImpl1(num_ops_per_thread);
    ::DDS::DataReaderListener_var drl5 =
        new DataReaderListenerImpl1(num_ops_per_thread);

    if (topics & TOPIC_T1) {
      dr1 = sub->create_datareader(topic1, dr_qos, drl1,
                                   ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
    }

    if (topics & TOPIC_T2) {
      dr2_1 = sub->create_datareader(topic2, dr_qos, drl2_1,
                                     ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);

      dr2_2 = sub->create_datareader(topic2, dr_qos, drl2_2,
                                     ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);

      dr2_3 = sub->create_datareader(topic2, dr_qos, drl2_3,
                                     ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
    }

    if (topics & TOPIC_T3) {
      dr3 = sub->create_datareader(topic3, dr_qos, drl3,
                                   ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
    }

    if (topics & TOPIC_T4) {
      dr4 = sub->create_datareader(topic4, dr_qos, drl4,
                                   ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
    }

    if (topics & TOPIC_T5) {
      dr5 = sub->create_datareader(topic5, dr_qos, drl5,
                                   ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
    }

    if (topics & TOPIC_T1) {
      const DataReaderListenerImpl* const drl_servant =
        dynamic_cast<const DataReaderListenerImpl*>(drl1.in());
      if (!check_listener(drl_servant, num_ops_per_thread, ACE_TEXT(MY_TOPIC1)))
        status = 1;
    }

    if (topics & TOPIC_T2) {
      const DataReaderListenerImpl* const drl2_1srv =
        dynamic_cast<const DataReaderListenerImpl*>(drl2_1.in());
      if (!check_listener(drl2_1srv, num_ops_per_thread, ACE_TEXT(MY_TOPIC2)))
        status = 1;

      const DataReaderListenerImpl* const drl2_2srv =
        dynamic_cast<const DataReaderListenerImpl*>(drl2_2.in());
      if (!check_listener(drl2_2srv, num_ops_per_thread, ACE_TEXT(MY_TOPIC2)))
        status = 1;

      const DataReaderListenerImpl* const drl2_3srv =
        dynamic_cast<const DataReaderListenerImpl*>(drl2_3.in());
      if (!check_listener(drl2_3srv, num_ops_per_thread, ACE_TEXT(MY_TOPIC2)))
        status = 1;
    }

    if (topics & TOPIC_T3) {
      const DataReaderListenerImpl* const drl_servant =
        dynamic_cast<const DataReaderListenerImpl*>(drl3.in());
      if (!check_listener(drl_servant, num_ops_per_thread, ACE_TEXT(MY_TOPIC3)))
        status = 1;
    }

    if (topics & TOPIC_T4) {
      const DataReaderListenerImpl* const drl_servant =
        dynamic_cast<const DataReaderListenerImpl*>(drl4.in());
      if (!check_listener(drl_servant, num_ops_per_thread, ACE_TEXT(MY_TOPIC4)))
        status = 1;
    }

    if (topics & TOPIC_T5) {
      const DataReaderListenerImpl* const drl_servant =
        dynamic_cast<const DataReaderListenerImpl*>(drl5.in());
      if (!check_listener(drl_servant, num_ops_per_thread, ACE_TEXT(MY_TOPIC5)))
        status = 1;
    }

    if (topics & TOPIC_T1) {
      wait_for_file(ACE_TEXT(MY_TOPIC1), pub_finished_filename);
    }

    if (topics & TOPIC_T2) {
      wait_for_file(ACE_TEXT(MY_TOPIC2), pub_finished_filename);
    }

    if (topics & TOPIC_T3) {
      wait_for_file(ACE_TEXT(MY_TOPIC3), pub_finished_filename);
    }

    if (topics & TOPIC_T4) {
      wait_for_file(ACE_TEXT(MY_TOPIC4), pub_finished_filename);
    }

    if (topics & TOPIC_T5) {
      wait_for_file(ACE_TEXT(MY_TOPIC5), pub_finished_filename);
    }

    if (publish_topics) {
      bool writers_finished = false;

      while (!writers_finished && num_writers) {
        writers_finished = true;

        for (int m = 0; m < num_writers; m++) {
          writers_finished = writers_finished && writers[m]->is_finished();
        }

        if (!writers_finished) ACE_OS::sleep(small_time);
      }
    }

    if (publish_topics & TOPIC_T6) {
      ACE_TString t6_filename = ACE_TEXT(MY_TOPIC6) + pub_finished_filename;
      FILE* writers_completed =
        ACE_OS::fopen(t6_filename.c_str(), ACE_TEXT("w"));
      if (writers_completed == 0) {
        ACE_ERROR((LM_ERROR,
                   ACE_TEXT("(%P|%t) ERROR: Unable to create publisher ")
                   ACE_TEXT("completed file\n")));
        status = 1;
      } else {
        ACE_OS::fclose(writers_completed);
      }
    }

    if (publish_topics & TOPIC_T7) {
      ACE_TString t7_filename = ACE_TEXT(MY_TOPIC7) + pub_finished_filename;
      FILE* writers_completed =
        ACE_OS::fopen(t7_filename.c_str(), ACE_TEXT("w"));
      if (writers_completed == 0) {
        ACE_ERROR((LM_ERROR,
                   ACE_TEXT("(%P|%t) ERROR: Unable to create publisher ")
                   ACE_TEXT("completed file\n")));
        status = 1;
      } else {
        ACE_OS::fclose(writers_completed);
      }
    }

    ACE_DEBUG((LM_DEBUG, "(%P|%t) delete contained entities on pub\n"));
    pub->delete_contained_entities();

    for (int n = 0; n < num_writers; ++n) {
      delete writers[n];
    }
    delete [] writers;

    dp->delete_contained_entities();

    dpf->delete_participant(dp);

    TheServiceParticipant->shutdown();

  } catch (const TestException&) {
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT("(%P|%t) TestException caught in main.cpp.\n")));
    return 1;

  } catch (const CORBA::Exception& ex) {
    ex._tao_print_exception ("Exception caught in main.cpp:");
    return 1;
  }

  return status;
}
Beispiel #25
0
/* returns size of the file in bytes if OK, otherwise a negative error */
static long long get_cached_file (const char * user_id, const char * url, const char * file_id, const char * instance_id, const char * file_name, char * file_path, sem * s, int convert_to_disk, long long limit_mb) 
{
    char tmp_digest_path [BUFSIZE];
	char cached_dir      [BUFSIZE]; 
	char cached_path     [BUFSIZE];
	char staging_path    [BUFSIZE];
	char digest_path     [BUFSIZE];

	snprintf (file_path,       BUFSIZE, "%s/%s/%s/%s",    sc_instance_path, user_id, instance_id, file_name);
	snprintf (tmp_digest_path, BUFSIZE, "%s-digest",      file_path);
	snprintf (cached_dir,      BUFSIZE, "%s/%s/cache/%s", sc_instance_path, EUCALYPTUS_ADMIN, file_id); /* cache is in admin's directory */
	snprintf (cached_path,     BUFSIZE, "%s/%s",          cached_dir, file_name);
	snprintf (staging_path,    BUFSIZE, "%s-staging",     cached_path);
	snprintf (digest_path,     BUFSIZE, "%s-digest",      cached_path);

retry:

    /* under a lock, figure out the state of the file */
    sem_p (sc_sem); /***** acquire lock *****/
    ensure_subdirectory_exists (file_path); /* creates missing directories */

	struct stat mystat;
    int cached_exists  = ! stat (cached_path, &mystat);
    int staging_exists = ! stat (staging_path, &mystat);

    int e = ERROR;
    int action;
    enum { ABORT, VERIFY, WAIT, STAGE };
    if ( staging_exists ) {
        action = WAIT;
    } else {
        if ( cached_exists ) {
            action = VERIFY;
        } else {
            action = STAGE;
        }
    }

    /* we return the sum of these */
    long long file_size_b = 0;
    long long digest_size_b = 0;
   
    /* while still under lock, decide whether to cache */
    int should_cache = 0;
    if (action==STAGE) { 
        e = walrus_object_by_url (url, tmp_digest_path, 0); /* get the digest to see how big the file is */
        if (e==OK && stat (tmp_digest_path, &mystat)) {
            digest_size_b = (long long)mystat.st_size;
        }
        if (e==OK) {
            /* pull the size out of the digest */
            char * xml_file = file2str (tmp_digest_path);
            if (xml_file) {
                file_size_b = str2longlong (xml_file, "<size>", "</size>");
                free (xml_file);
            }
            if (file_size_b > 0) {
                long long full_size_b = file_size_b+digest_size_b;
                if (convert_to_disk) {
                    full_size_b += swap_size_mb*MEGABYTE + MEGABYTE; /* TODO: take into account extra padding required for disks (over partitions) */
                }
                if ( full_size_b/MEGABYTE + 1 > limit_mb ) {
                    logprintfl (EUCAFATAL, "error: insufficient disk capacity remaining (%lldMB) in VM Type of instance %s for component %s\n", limit_mb, instance_id, file_name);
                    action = ABORT;
                    
                } else if ( ok_to_cache (cached_path, full_size_b) ) { /* will invalidate the cache, if needed */
                    ensure_path_exists (cached_dir); /* creates missing directories */
                    should_cache = 1;
                    if ( touch (staging_path) ) { /* indicate that we'll be caching it */
                        logprintfl (EUCAERROR, "error: failed to create staging file %s\n", staging_path);
                        action = ABORT;
                    }
                }
            } else {
                logprintfl (EUCAERROR, "error: failed to obtain file size from digest %s\n", url);
                action = ABORT;
            }
        } else {
            logprintfl (EUCAERROR, "error: failed to obtain digest from %s\n", url);
            action = ABORT;
        }
    }
    sem_v (sc_sem); /***** release lock *****/
    
    switch (action) {
    case STAGE:
        logprintfl (EUCAINFO, "downloding image into %s...\n", file_path);		
        e = walrus_image_by_manifest_url (url, file_path, 1);

        /* for KVM, convert partition into disk */
        if (e==OK && convert_to_disk) { 
            sem_p (s);
            /* for the cached disk swap==0 and ephemeral==0 as we'll append them below */
            if ((e=vrun("%s %s %d %d", disk_convert_command_path, file_path, 0, 0))!=0) {
                logprintfl (EUCAERROR, "error: partition-to-disk image conversion command failed\n");
            }
            sem_v (s);
            
            /* recalculate file size now that it was converted */
            if ( stat (file_path, &mystat ) != 0 ) {
                logprintfl (EUCAERROR, "error: file %s not found\n", file_path);
            } else if (mystat.st_size < 1) {
                logprintfl (EUCAERROR, "error: file %s has the size of 0\n", file_path);
            } else {
                file_size_b = (long long)mystat.st_size;
            }
        }

        /* cache the partition or disk, if possible */
        if ( e==OK && should_cache ) {
            if ( (e=vrun ("cp -a %s %s", file_path, cached_path)) != 0) {
                logprintfl (EUCAERROR, "failed to copy file %s into cache at %s\n", file_path, cached_path);
            }
            if ( e==OK && (e=vrun ("cp -a %s %s", tmp_digest_path, digest_path)) != 0) {
                logprintfl (EUCAERROR, "failed to copy digest file %s into cache at %s\n", tmp_digest_path, digest_path);
            }
        }
        
        sem_p (sc_sem);
        if (should_cache) {
            unlink (staging_path);            
        }
        if ( e ) {
            logprintfl (EUCAERROR, "error: failed to download file from Walrus into %s\n", file_path);
            unlink (file_path);
            unlink (tmp_digest_path);
            if (should_cache) {
                unlink (cached_path);
                unlink (digest_path);
                if ( rmdir(cached_dir) ) {
                    logprintfl (EUCAWARN, "warning: failed to remove cache directory %s\n", cached_dir);
                }
            }
        }
        sem_v (sc_sem);
        break;
        
    case WAIT:
        logprintfl (EUCAINFO, "waiting for disapperance of %s...\n", staging_path);
        /* wait for staging_path to disappear, which means both either the
         * download succeeded or it failed */
        if ( (e=wait_for_file (NULL, staging_path, 180, "cached image")) ) 
            return 0L;        
        /* yes, it is OK to fall through */
        
    case VERIFY:
        logprintfl (EUCAINFO, "verifying cached file in %s...\n", cached_path);
        sem_p (sc_sem); /***** acquire lock *****/
        e = ERROR;
        if ( stat (cached_path, &mystat ) != 0 ) {
            logprintfl (EUCAERROR, "error: file %s not found\n", cached_path);
        } else if (mystat.st_size < 1) {
            logprintfl (EUCAERROR, "error: file %s has the size of 0\n", cached_path);
        } else if ((e=walrus_verify_digest (url, digest_path))<0) {
            /* negative status => digest changed */
            unlink (cached_path);
            unlink (staging_path); /* TODO: needed? */
            unlink (digest_path);
            if ( rmdir (cached_dir) ) {
                logprintfl (EUCAWARN, "warning: failed to remove cache directory %s\n", cached_dir);
            } else {
                logprintfl (EUCAINFO, "due to failure, removed cache directory %s\n", cached_dir);
            }
        } else {
            file_size_b = mystat.st_size;

            /* touch the digest so cache can use mtime for invalidation */
            if ( touch (digest_path) ) {
                logprintfl (EUCAERROR, "error: failed to touch digest file %s\n", digest_path);
            } else if ( stat (digest_path, &mystat) ) {
                logprintfl (EUCAERROR, "error: digest file %s not found\n", digest_path);
            } else {
                digest_size_b = (long long)mystat.st_size;
            }
        }
        sem_v (sc_sem); /***** release lock *****/
        
        if (e<0) { /* digest changed */
            if (action==VERIFY) { /* i.e. we did not download/waited for this file */
                /* try downloading anew */
                goto retry;
            } else {
                logprintfl (EUCAERROR, "error: digest mismatch, giving up\n");
                return 0L;
            }
        } else if (e>0) { /* problem with file or digest */
            return 0L;
            
        } else { /* all good - copy it, finally */
            ensure_subdirectory_exists (file_path); /* creates missing directories */            
            if ( (e=vrun ("cp -a %s %s", cached_path, file_path)) != 0) {
                logprintfl (EUCAERROR, "failed to copy file %s from cache at %s\n", file_path, cached_path);
                return 0L;
            }
        }
        break;
        
    case ABORT:
        logprintfl (EUCAERROR, "get_cached_file() failed (errno=%d)\n", e);
        e = ERROR;
    }

    if (e==OK && file_size_b > 0 && convert_to_disk ) { // if all went well above
        long long ephemeral_mb = limit_mb - swap_size_mb - (file_size_b+digest_size_b)/MEGABYTE;
        if ( swap_size_mb>0L || ephemeral_mb>0L ) {
            sem_p (s);
            if ((e=vrun("%s %s %lld %lld", disk_convert_command_path, file_path, swap_size_mb, ephemeral_mb))!=0) {
                logprintfl (EUCAERROR, "error: failed to add swap or ephemeral to the disk image\n");
            }
            sem_v (s);

            /* recalculate file size (again!) now that it was converted */
            if ( stat (file_path, &mystat ) != 0 ) {
                logprintfl (EUCAERROR, "error: file %s not found\n", file_path);
            } else if (mystat.st_size < 1) {
                logprintfl (EUCAERROR, "error: file %s has the size of 0\n", file_path);
            } else {
                file_size_b = (long long)mystat.st_size;
            }
        }
    }

    if (e==OK && action!=ABORT)
        return file_size_b + digest_size_b;
    return 0L;
}
Beispiel #26
0
static void mount_and_run(struct fstab *fstab)
{
    struct fstab_part *p = fstab_find_by_path(fstab, "/data");
    if(!p)
    {
        ERROR("Failed to find /data partition in fstab\n");
        return;
    }

    if(wait_for_file(p->device, 5) < 0)
    {
        ERROR("Waiting too long for dev %s", p->device);
        return;
    }

    // Remove nosuid flag, because secondary ROMs have
    // su binaries on /data
    p->mountflags &= ~(MS_NOSUID);

    mkdir(REALDATA, 0755);
    if (mount(p->device, REALDATA, p->type, p->mountflags, p->options) < 0)
    {
        ERROR("Failed to mount /realdata, err %d, trying all filesystems\n", errno);

        const char *fs_types[] = { "ext4", "f2fs", "ext3", "ext2" };
        const char *fs_opts [] = {
            "barrier=1,data=ordered,nomblk_io_submit,noauto_da_alloc,errors=panic", // ext4
            "inline_xattr,flush_merge,errors=recover", // f2fs
            "", // ext3
            "" // ext2
        };

        int mounted = 0;
        size_t i;
        for(i = 0; i < ARRAY_SIZE(fs_types); ++i)
        {
            ERROR("Trying to mount %s with fs %s\n", p->device, fs_types[i]);
            if(mount(p->device, REALDATA, fs_types[i], p->mountflags, fs_opts[i]) >= 0)
            {
                ERROR("/realdata successfuly mounted with fs %s\n", fs_types[i]);
                mounted = 1;
                break;
            }
        }

        if(!mounted)
        {
            ERROR("Failed to mount /realdata with all possible filesystems!");
            return;
        }
    }

    if(find_multirom() == -1)
    {
        ERROR("Could not find multirom folder!");
        return;
    }

    adb_init(path_multirom);
    run_multirom();
    adb_quit();
}
Beispiel #27
0
/* mount <type> <device> <path> <flags ...> <options> */
int do_mount(int nargs, char **args)
{
    char tmp[64];
    char *source, *target, *system;
    char *options = NULL;
    unsigned flags = 0;
    int n, i;
    int wait = 0;

    for (n = 4; n < nargs; n++) {
        for (i = 0; mount_flags[i].name; i++) {
            if (!strcmp(args[n], mount_flags[i].name)) {
                flags |= mount_flags[i].flag;
                break;
            }
        }

        if (!mount_flags[i].name) {
            if (!strcmp(args[n], "wait"))
                wait = 1;
            /* if our last argument isn't a flag, wolf it up as an option string */
            else if (n + 1 == nargs)
                options = args[n];
        }
    }

    system = args[1];
    source = args[2];
    target = args[3];

    if (!strncmp(source, "mtd@", 4)) {
        n = mtd_name_to_number(source + 4);
        if (n < 0) {
            return -1;
        }

        sprintf(tmp, "/dev/block/mtdblock%d", n);

        if (wait)
            wait_for_file(tmp, COMMAND_RETRY_TIMEOUT);
        if (mount(tmp, target, system, flags, options) < 0) {
            return -1;
        }

        goto exit_success;
    } else if (!strncmp(source, "loop@", 5)) {
        int mode, loop, fd;
        struct loop_info info;

        mode = (flags & MS_RDONLY) ? O_RDONLY : O_RDWR;
        fd = open(source + 5, mode);
        if (fd < 0) {
            return -1;
        }

        for (n = 0; ; n++) {
            sprintf(tmp, "/dev/block/loop%d", n);
            loop = open(tmp, mode);
            if (loop < 0) {
                return -1;
            }

            /* if it is a blank loop device */
            if (ioctl(loop, LOOP_GET_STATUS, &info) < 0 && errno == ENXIO) {
                /* if it becomes our loop device */
                if (ioctl(loop, LOOP_SET_FD, fd) >= 0) {
                    close(fd);

                    if (mount(tmp, target, system, flags, options) < 0) {
                        ioctl(loop, LOOP_CLR_FD, 0);
                        close(loop);
                        return -1;
                    }

                    close(loop);
                    goto exit_success;
                }
            }

            close(loop);
        }

        close(fd);
        ERROR("out of loopback devices");
        return -1;
    } else {
        if (wait)
            wait_for_file(source, COMMAND_RETRY_TIMEOUT);
        if (mount(source, target, system, flags, options) < 0) {
            return -1;
        }

    }

exit_success:
    return 0;

}
Beispiel #28
0
/* When multiple fstab records share the same mount_point, it will
 * try to mount each one in turn, and ignore any duplicates after a
 * first successful mount.
 * Returns -1 on error, and  FS_MGR_MNTALL_* otherwise.
 */
int fs_mgr_mount_all(struct fstab *fstab)
{
    int i = 0;
    int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
    int error_count = 0;
    int mret = -1;
    int mount_errno = 0;
    int attempted_idx = -1;

    if (!fstab) {
        return -1;
    }

    for (i = 0; i < fstab->num_entries; i++) {
        /* Don't mount entries that are managed by vold */
        if (fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) {
            continue;
        }

        /* Skip swap and raw partition entries such as boot, recovery, etc */
        if (!strcmp(fstab->recs[i].fs_type, "swap") ||
            !strcmp(fstab->recs[i].fs_type, "emmc") ||
            !strcmp(fstab->recs[i].fs_type, "mtd")) {
            continue;
        }

        if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
            wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
        }

        if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
            int rc = fs_mgr_setup_verity(&fstab->recs[i]);
            if (device_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
                INFO("Verity disabled");
            } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
                ERROR("Could not set up verified partition, skipping!\n");
                continue;
            }
        }
        int last_idx_inspected;
        int top_idx = i;

        mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
        i = last_idx_inspected;
        mount_errno = errno;

        /* Deal with encryptability. */
        if (!mret) {
            /* If this is encryptable, need to trigger encryption */
            if (   (fstab->recs[attempted_idx].fs_mgr_flags & MF_FORCECRYPT)
                || (device_is_force_encrypted()
                    && fs_mgr_is_encryptable(&fstab->recs[attempted_idx]))) {
                if (umount(fstab->recs[attempted_idx].mount_point) == 0) {
                    if (encryptable == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
                        ERROR("Will try to encrypt %s %s\n", fstab->recs[attempted_idx].mount_point,
                              fstab->recs[attempted_idx].fs_type);
                        encryptable = FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION;
                    } else {
                        ERROR("Only one encryptable/encrypted partition supported\n");
                        encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
                    }
                } else {
                    INFO("Could not umount %s - allow continue unencrypted\n",
                         fstab->recs[attempted_idx].mount_point);
                    continue;
                }
            }
            /* Success!  Go get the next one */
            continue;
        }

        /* mount(2) returned an error, handle the encryptable/formattable case */
        bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
        if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
            fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) {
            /* top_idx and attempted_idx point at the same partition, but sometimes
             * at two different lines in the fstab.  Use the top one for formatting
             * as that is the preferred one.
             */
            ERROR("%s(): %s is wiped and %s %s is formattable. Format it.\n", __func__,
                  fstab->recs[top_idx].blk_device, fstab->recs[top_idx].mount_point,
                  fstab->recs[top_idx].fs_type);
            if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
                strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
                int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY, 0644);
                if (fd >= 0) {
                    INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc);
                    wipe_block_device(fd, get_file_size(fd));
                    close(fd);
                } else {
                    ERROR("%s(): %s wouldn't open (%s)\n", __func__,
                          fstab->recs[top_idx].key_loc, strerror(errno));
                }
            }
            if (fs_mgr_do_format(&fstab->recs[top_idx]) == 0) {
                /* Let's replay the mount actions. */
                i = top_idx - 1;
                continue;
            }
        }
        if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
            fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
            if (wiped) {
                ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__,
                      fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
                      fstab->recs[attempted_idx].fs_type);
                encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
                continue;
            } else {
                /* Need to mount a tmpfs at this mountpoint for now, and set
                 * properties that vold will query later for decrypting
                 */
                ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__,
                      fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
                      fstab->recs[attempted_idx].fs_type);
                if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
                    ++error_count;
                    continue;
                }
            }
            encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
        } else {
            ERROR("Failed to mount an un-encryptable or wiped partition on"
                   "%s at %s options: %s error: %s\n",
                   fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
                   fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
            ++error_count;
            continue;
        }
    }

    if (error_count) {
        return -1;
    } else {
        return encryptable;
    }
}
Beispiel #29
0
int main(int argc, const char * argv[]) {
    // insert code here...
    //std::cout << "Hello, World!\n";
    
    Palette c64palette(c64_colors, num_64_colors);
    Ditherer* ditherer = Ditherer::createC64Ditherer();
    
    const char* dirname = argv[1];
    const char* outdirname = argv[2];
    const char* out64fname = argv[3];
    
    int index = 0;
    char thisfname[256];
    char nextfname[256];
    char outfname[256];
    unsigned char* c64frame = NULL;
    
    FILE* fp = fopen(out64fname, "wb");
    NetPort port(192,168,1,25,99998,99999);
    Tools::Timer frameTimer;
    
    frameTimer.start();
    for (index = 1; index < 9999; index++)
    {
        // check if file can be opened
        sprintf(thisfname, "%s/%04d.ppm", dirname, index);
        sprintf(nextfname, "%s/%04d.ppm", dirname, index+1);
        
        wait_for_file(nextfname);
        printf("%s\n", thisfname);
        
        // open image
        Image inputImage(thisfname);
        int imWidth = inputImage.getWidth();
        int imHeight = inputImage.getHeight();
        Image halfImage(inputImage, imWidth/2, imHeight);
        
        Image* dithered = ditherer->createDitheredImageFromImageWithPalette(halfImage, c64palette);
        C64Image* c64im = (C64Image*)dithered;
        
        /*
        // test - output to new ppm
        sprintf(outfname, "%s/%04d.ppm", outdirname, index);
        Image fullImage(*dithered, imWidth, imHeight);
        fullImage.writePPM(outfname);
        */
        
        int c64FrameSize = c64im->getC64FrameSize();
        if (!c64frame)
        {
            c64frame = (unsigned char*)malloc(sizeof(unsigned char) * c64FrameSize);
        }
        float time = (float)index / 8.0;
        c64im->getC64Frame(c64frame, time);
        fwrite(c64frame, 1, c64FrameSize, fp);
        
        float thisTime = frameTimer.getTime();
        printf("pts %f, time %f\n", time, thisTime);
        while (thisTime < time)
        {
            float diff = time - thisTime;
            float usec = diff * 1000000.0;
            usleep(usec);
            thisTime = frameTimer.getTime();
        }
        // send bytes to port
        port.send(&c64frame[4], 9216);
        
        delete dithered;
    }
    fclose(fp);
    
    return 0;
}
Beispiel #30
0
int main(int argc, char *argv[])
{
    int i, res;
    static char *const cmd[] = { "/init", NULL };
    struct fstab *fstab = NULL;
    char *inject_path = NULL;
    char *mrom_dir = NULL;
    int force_inject = 0;

    for(i = 1; i < argc; ++i)
    {
        if(strcmp(argv[i], "-v") == 0)
        {
            printf("%d\n", VERSION_TRAMPOLINE);
            fflush(stdout);
            return 0;
        }
        else if(strstartswith(argv[i], "--inject="))
            inject_path = argv[i] + strlen("--inject=");
        else if(strstartswith(argv[i], "--mrom_dir="))
            mrom_dir = argv[i] + strlen("--mrom_dir=");
        else if(strcmp(argv[i], "-f") == 0)
            force_inject = 1;
    }

    if(inject_path)
    {
        if(!mrom_dir)
        {
            printf("--mrom_dir=[path to multirom's data dir] needs to be specified!\n");
            fflush(stdout);
            return 1;
        }

        mrom_set_dir(mrom_dir);
        mrom_set_log_tag("trampoline_inject");
        return inject_bootimg(inject_path, force_inject);
    }

    umask(000);

    // Init only the little we need, leave the rest for real init
    mkdir("/dev", 0755);
    mkdir("/dev/pts", 0755);
    mkdir("/dev/socket", 0755);
    mkdir("/proc", 0755);
    mkdir("/sys", 0755);

    mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
    mount("devpts", "/dev/pts", "devpts", 0, NULL);
    mount("proc", "/proc", "proc", 0, NULL);
    mount("sysfs", "/sys", "sysfs", 0, NULL);
    mount("pstore", "/sys/fs/pstore", "pstore", 0, NULL);

#if MR_USE_DEBUGFS_MOUNT
    // Mount the debugfs kernel sysfs
    mkdir("/sys/kernel/debug", 0755);
    mount("debugfs", "/sys/kernel/debug", "debugfs", 0, NULL);
#endif

    klog_init();
    // output all messages to dmesg,
    // but it is possible to filter out INFO messages
    klog_set_level(6);

    mrom_set_log_tag("trampoline");
    INFO("Running trampoline v%d\n", VERSION_TRAMPOLINE);

    if(is_charger_mode())
    {
        INFO("Charger mode detected, skipping multirom\n");
        goto run_main_init;
    }

#if MR_DEVICE_HOOKS >= 3
    tramp_hook_before_device_init();
#endif

    INFO("Initializing devices...\n");
    devices_init();
    INFO("Done initializing\n");

    if(wait_for_file("/dev/graphics/fb0", 5) < 0)
    {
        ERROR("Waiting too long for fb0");
        goto exit;
    }

#ifdef MR_POPULATE_BY_NAME_PATH
    //nkk71 M7 hack
    Populate_ByName_using_emmc();
#endif

    fstab = fstab_auto_load();
    if(!fstab)
        goto exit;

#if 0
    fstab_dump(fstab); //debug
#endif

    // mount and run multirom from sdcard
    if(mount_and_run(fstab) < 0 && mrom_is_second_boot())
    {
        ERROR("This is second boot and we couldn't mount /data, reboot!\n");
        sync();
        android_reboot(ANDROID_RB_RESTART, 0, 0);
        while(1)
            sleep(1);
    }

exit:
    if(fstab)
        fstab_destroy(fstab);

    // close and destroy everything
    devices_close();

run_main_init:
    umount("/dev/pts");
    rmdir("/dev/pts");
    rmdir("/dev/socket");

    if(access(KEEP_REALDATA, F_OK) < 0)
    {
        umount(REALDATA);
        umount("/dev");
        rmdir(REALDATA);
        encryption_destroy();
    }

    encryption_cleanup();

#if MR_USE_DEBUGFS_MOUNT
    umount("/sys/kernel/debug");
#endif

    umount("/proc");
    umount("/sys/fs/pstore");
    umount("/sys");

    INFO("Running main_init\n");

    fixup_symlinks();

    chmod("/main_init", EXEC_MASK);
    rename("/main_init", "/init");

    res = execve(cmd[0], cmd, NULL);
    ERROR("execve returned %d %d %s\n", res, errno, strerror(errno));
    return 0;
}