/* 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; }
/* * Tries to mount any of the consecutive fstab entries that match * the mountpoint of the one given by fstab->recs[start_idx]. * * end_idx: On return, will be the last rec that was looked at. * attempted_idx: On return, will indicate which fstab rec * succeeded. In case of failure, it will be the start_idx. * Returns * -1 on failure with errno set to match the 1st mount failure. * 0 on success. */ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_idx, int *attempted_idx) { int i; int mount_errno = 0; int mounted = 0; if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) { errno = EINVAL; if (end_idx) *end_idx = start_idx; if (attempted_idx) *end_idx = start_idx; return -1; } /* Hunt down an fstab entry for the same mount point that might succeed */ for (i = start_idx; /* We required that fstab entries for the same mountpoint be consecutive */ i < fstab->num_entries && !strcmp(fstab->recs[start_idx].mount_point, fstab->recs[i].mount_point); i++) { /* * Don't try to mount/encrypt the same mount point again. * Deal with alternate entries for the same point which are required to be all following * each other. */ if (mounted) { ERROR("%s(): skipping fstab dup mountpoint=%s rec[%d].fs_type=%s already mounted as %s.\n", __func__, fstab->recs[i].mount_point, i, fstab->recs[i].fs_type, fstab->recs[*attempted_idx].fs_type); continue; } 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); } if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, &fstab->recs[i])) { *attempted_idx = i; mounted = 1; if (i != start_idx) { ERROR("%s(): Mounted %s on %s with fs_type=%s instead of %s\n", __func__, fstab->recs[i].blk_device, fstab->recs[i].mount_point, fstab->recs[i].fs_type, fstab->recs[start_idx].fs_type); } } else { /* back up errno for crypto decisions */ mount_errno = errno; } } /* Adjust i for the case where it was still withing the recs[] */ if (i < fstab->num_entries) --i; *end_idx = i; if (!mounted) { *attempted_idx = start_idx; errno = mount_errno; return -1; } return 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; }
/* 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; }
FRESULT pf_mount ( FATFS *fs /* Pointer to new file system object */ ) { BYTE fmt, buf[36] = {0}; DWORD bsect, fsize, tsect, mclst; FatFs = 0; if (disk_initialize() & STA_NOINIT) /* Check if the drive is ready or not */ return FR_NOT_READY; /* Search FAT partition on the drive */ bsect = 0; fmt = check_fs(buf, bsect); /* Check sector 0 as an SFD format */ if (fmt == 1) { /* Not an FAT boot record, it may be FDISK format */ /* Check a partition listed in top of the partition table */ if (disk_readp(buf, bsect, MBR_Table, 16)) { /* 1st partition entry */ fmt = 3; } else { if (buf[4]) { /* Is the partition existing? */ bsect = LD_DWORD(&buf[8]); /* Partition offset in LBA */ fmt = check_fs(buf, bsect); /* Check the partition */ } } } if (fmt == 3) return FR_DISK_ERR; if (fmt) return FR_NO_FILESYSTEM; /* No valid FAT patition is found */ /* Initialize the file system object */ if (disk_readp(buf, bsect, 13, sizeof (buf))) return FR_DISK_ERR; fsize = LD_WORD(buf+BPB_FATSz16-13); /* Number of sectors per FAT */ if (!fsize) fsize = LD_DWORD(buf+BPB_FATSz32-13); fsize *= buf[BPB_NumFATs-13]; /* Number of sectors in FAT area */ fs->fatbase = bsect + LD_WORD(buf+BPB_RsvdSecCnt-13); /* FAT start sector (lba) */ fs->csize = buf[BPB_SecPerClus-13]; /* Number of sectors per cluster */ fs->n_rootdir = LD_WORD(buf+BPB_RootEntCnt-13); /* Nmuber of root directory entries */ tsect = LD_WORD(buf+BPB_TotSec16-13); /* Number of sectors on the file system */ if (!tsect) tsect = LD_DWORD(buf+BPB_TotSec32-13); mclst = (tsect /* Last cluster# + 1 */ - LD_WORD(buf+BPB_RsvdSecCnt-13) - fsize - fs->n_rootdir / 16 ) / fs->csize + 2; fs->n_fatent = (CLUST)mclst; fmt = 0; /* Determine the FAT sub type */ if (_FS_FAT12 && mclst < 0xFF7) fmt = FS_FAT12; if (_FS_FAT16 && mclst >= 0xFF8 && mclst < 0xFFF7) fmt = FS_FAT16; if (_FS_FAT32 && mclst >= 0xFFF7) fmt = FS_FAT32; if (!fmt) return FR_NO_FILESYSTEM; fs->fs_type = fmt; if (_FS_32ONLY || (_FS_FAT32 && fmt == FS_FAT32)) fs->dirbase = LD_DWORD(buf+(BPB_RootClus-13)); /* Root directory start cluster */ else fs->dirbase = fs->fatbase + fsize; /* Root directory start sector (lba) */ fs->database = fs->fatbase + fsize + fs->n_rootdir / 16; /* Data start sector (lba) */ fs->flag = 0; FatFs = fs; return FR_OK; }
/* 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; }
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; }
/* 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; }
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; }