Home | History | Annotate | Download | only in fs_mgr
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <ctype.h>
     18 #include <dirent.h>
     19 #include <errno.h>
     20 #include <fcntl.h>
     21 #include <libgen.h>
     22 #include <stdio.h>
     23 #include <stdlib.h>
     24 #include <string.h>
     25 #include <sys/ioctl.h>
     26 #include <sys/mount.h>
     27 #include <sys/stat.h>
     28 #include <sys/swap.h>
     29 #include <sys/types.h>
     30 #include <sys/wait.h>
     31 #include <time.h>
     32 #include <unistd.h>
     33 
     34 #include <memory>
     35 
     36 #include <android-base/file.h>
     37 #include <android-base/properties.h>
     38 #include <android-base/stringprintf.h>
     39 #include <android-base/unique_fd.h>
     40 #include <cutils/android_reboot.h>
     41 #include <cutils/partition_utils.h>
     42 #include <cutils/properties.h>
     43 #include <ext4_utils/ext4.h>
     44 #include <ext4_utils/ext4_crypt_init_extensions.h>
     45 #include <ext4_utils/ext4_sb.h>
     46 #include <ext4_utils/ext4_utils.h>
     47 #include <ext4_utils/wipe.h>
     48 #include <linux/fs.h>
     49 #include <linux/loop.h>
     50 #include <linux/magic.h>
     51 #include <log/log_properties.h>
     52 #include <logwrap/logwrap.h>
     53 
     54 #include "fs_mgr.h"
     55 #include "fs_mgr_avb.h"
     56 #include "fs_mgr_priv.h"
     57 #include "fs_mgr_priv_dm_ioctl.h"
     58 
     59 #define KEY_LOC_PROP   "ro.crypto.keyfile.userdata"
     60 #define KEY_IN_FOOTER  "footer"
     61 
     62 #define E2FSCK_BIN      "/system/bin/e2fsck"
     63 #define F2FS_FSCK_BIN   "/system/bin/fsck.f2fs"
     64 #define MKSWAP_BIN      "/system/bin/mkswap"
     65 #define TUNE2FS_BIN     "/system/bin/tune2fs"
     66 
     67 #define FSCK_LOG_FILE   "/dev/fscklogs/log"
     68 
     69 #define ZRAM_CONF_DEV   "/sys/block/zram0/disksize"
     70 #define ZRAM_CONF_MCS   "/sys/block/zram0/max_comp_streams"
     71 
     72 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
     73 
     74 // record fs stat
     75 enum FsStatFlags {
     76     FS_STAT_IS_EXT4 = 0x0001,
     77     FS_STAT_NEW_IMAGE_VERSION = 0x0002,
     78     FS_STAT_E2FSCK_F_ALWAYS = 0x0004,
     79     FS_STAT_UNCLEAN_SHUTDOWN = 0x0008,
     80     FS_STAT_QUOTA_ENABLED = 0x0010,
     81     FS_STAT_TUNE2FS_FAILED = 0x0020,
     82     FS_STAT_RO_MOUNT_FAILED = 0x0040,
     83     FS_STAT_RO_UNMOUNT_FAILED = 0x0080,
     84     FS_STAT_FULL_MOUNT_FAILED = 0x0100,
     85     FS_STAT_E2FSCK_FAILED = 0x0200,
     86     FS_STAT_E2FSCK_FS_FIXED = 0x0400,
     87     FS_STAT_EXT4_INVALID_MAGIC = 0x0800,
     88 };
     89 
     90 /*
     91  * gettime() - returns the time in seconds of the system's monotonic clock or
     92  * zero on error.
     93  */
     94 static time_t gettime(void)
     95 {
     96     struct timespec ts;
     97     int ret;
     98 
     99     ret = clock_gettime(CLOCK_MONOTONIC, &ts);
    100     if (ret < 0) {
    101         PERROR << "clock_gettime(CLOCK_MONOTONIC) failed";
    102         return 0;
    103     }
    104 
    105     return ts.tv_sec;
    106 }
    107 
    108 static int wait_for_file(const char *filename, int timeout)
    109 {
    110     struct stat info;
    111     time_t timeout_time = gettime() + timeout;
    112     int ret = -1;
    113 
    114     while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0))
    115         usleep(10000);
    116 
    117     return ret;
    118 }
    119 
    120 static void log_fs_stat(const char* blk_device, int fs_stat)
    121 {
    122     if ((fs_stat & FS_STAT_IS_EXT4) == 0) return; // only log ext4
    123     std::string msg = android::base::StringPrintf("\nfs_stat,%s,0x%x\n", blk_device, fs_stat);
    124     android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(FSCK_LOG_FILE, O_WRONLY | O_CLOEXEC |
    125                                                         O_APPEND | O_CREAT, 0664)));
    126     if (fd == -1 || !android::base::WriteStringToFd(msg, fd)) {
    127         LWARNING << __FUNCTION__ << "() cannot log " << msg;
    128     }
    129 }
    130 
    131 static bool should_force_check(int fs_stat) {
    132     return fs_stat & (FS_STAT_E2FSCK_F_ALWAYS | FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED |
    133                       FS_STAT_TUNE2FS_FAILED | FS_STAT_RO_MOUNT_FAILED | FS_STAT_RO_UNMOUNT_FAILED |
    134                       FS_STAT_FULL_MOUNT_FAILED | FS_STAT_E2FSCK_FAILED);
    135 }
    136 
    137 static void check_fs(const char *blk_device, char *fs_type, char *target, int *fs_stat)
    138 {
    139     int status;
    140     int ret;
    141     long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
    142     char tmpmnt_opts[64] = "errors=remount-ro";
    143     const char* e2fsck_argv[] = {E2FSCK_BIN, "-y", blk_device};
    144     const char* e2fsck_forced_argv[] = {E2FSCK_BIN, "-f", "-y", blk_device};
    145 
    146     /* Check for the types of filesystems we know how to check */
    147     if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
    148         if (*fs_stat & FS_STAT_EXT4_INVALID_MAGIC) {  // will fail, so do not try
    149             return;
    150         }
    151         /*
    152          * First try to mount and unmount the filesystem.  We do this because
    153          * the kernel is more efficient than e2fsck in running the journal and
    154          * processing orphaned inodes, and on at least one device with a
    155          * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes
    156          * to do what the kernel does in about a second.
    157          *
    158          * After mounting and unmounting the filesystem, run e2fsck, and if an
    159          * error is recorded in the filesystem superblock, e2fsck will do a full
    160          * check.  Otherwise, it does nothing.  If the kernel cannot mount the
    161          * filesytsem due to an error, e2fsck is still run to do a full check
    162          * fix the filesystem.
    163          */
    164         if (!(*fs_stat & FS_STAT_FULL_MOUNT_FAILED)) {  // already tried if full mount failed
    165             errno = 0;
    166             if (!strcmp(fs_type, "ext4")) {
    167                 // This option is only valid with ext4
    168                 strlcat(tmpmnt_opts, ",nomblk_io_submit", sizeof(tmpmnt_opts));
    169             }
    170             ret = mount(blk_device, target, fs_type, tmpmnt_flags, tmpmnt_opts);
    171             PINFO << __FUNCTION__ << "(): mount(" << blk_device << "," << target << "," << fs_type
    172                   << ")=" << ret;
    173             if (!ret) {
    174                 bool umounted = false;
    175                 int retry_count = 5;
    176                 while (retry_count-- > 0) {
    177                     umounted = umount(target) == 0;
    178                     if (umounted) {
    179                         LINFO << __FUNCTION__ << "(): unmount(" << target << ") succeeded";
    180                         break;
    181                     }
    182                     PERROR << __FUNCTION__ << "(): umount(" << target << ") failed";
    183                     if (retry_count) sleep(1);
    184                 }
    185                 if (!umounted) {
    186                     // boot may fail but continue and leave it to later stage for now.
    187                     PERROR << __FUNCTION__ << "(): umount(" << target << ") timed out";
    188                     *fs_stat |= FS_STAT_RO_UNMOUNT_FAILED;
    189                 }
    190             } else {
    191                 *fs_stat |= FS_STAT_RO_MOUNT_FAILED;
    192             }
    193         }
    194 
    195         /*
    196          * Some system images do not have e2fsck for licensing reasons
    197          * (e.g. recent SDK system images). Detect these and skip the check.
    198          */
    199         if (access(E2FSCK_BIN, X_OK)) {
    200             LINFO << "Not running " << E2FSCK_BIN << " on " << blk_device
    201                   << " (executable not in system image)";
    202         } else {
    203             LINFO << "Running " << E2FSCK_BIN << " on " << blk_device;
    204             if (should_force_check(*fs_stat)) {
    205                 ret = android_fork_execvp_ext(
    206                     ARRAY_SIZE(e2fsck_forced_argv), const_cast<char**>(e2fsck_forced_argv), &status,
    207                     true, LOG_KLOG | LOG_FILE, true, const_cast<char*>(FSCK_LOG_FILE), NULL, 0);
    208             } else {
    209                 ret = android_fork_execvp_ext(
    210                     ARRAY_SIZE(e2fsck_argv), const_cast<char**>(e2fsck_argv), &status, true,
    211                     LOG_KLOG | LOG_FILE, true, const_cast<char*>(FSCK_LOG_FILE), NULL, 0);
    212             }
    213 
    214             if (ret < 0) {
    215                 /* No need to check for error in fork, we can't really handle it now */
    216                 LERROR << "Failed trying to run " << E2FSCK_BIN;
    217                 *fs_stat |= FS_STAT_E2FSCK_FAILED;
    218             } else if (status != 0) {
    219                 LINFO << "e2fsck returned status 0x" << std::hex << status;
    220                 *fs_stat |= FS_STAT_E2FSCK_FS_FIXED;
    221             }
    222         }
    223     } else if (!strcmp(fs_type, "f2fs")) {
    224             const char *f2fs_fsck_argv[] = {
    225                     F2FS_FSCK_BIN,
    226                     "-a",
    227                     blk_device
    228             };
    229         LINFO << "Running " << F2FS_FSCK_BIN << " -a " << blk_device;
    230 
    231         ret = android_fork_execvp_ext(ARRAY_SIZE(f2fs_fsck_argv),
    232                                       const_cast<char **>(f2fs_fsck_argv),
    233                                       &status, true, LOG_KLOG | LOG_FILE,
    234                                       true, const_cast<char *>(FSCK_LOG_FILE),
    235                                       NULL, 0);
    236         if (ret < 0) {
    237             /* No need to check for error in fork, we can't really handle it now */
    238             LERROR << "Failed trying to run " << F2FS_FSCK_BIN;
    239         }
    240     }
    241 
    242     return;
    243 }
    244 
    245 /* Function to read the primary superblock */
    246 static int read_super_block(int fd, struct ext4_super_block *sb)
    247 {
    248     off64_t ret;
    249 
    250     ret = lseek64(fd, 1024, SEEK_SET);
    251     if (ret < 0)
    252         return ret;
    253 
    254     ret = read(fd, sb, sizeof(*sb));
    255     if (ret < 0)
    256         return ret;
    257     if (ret != sizeof(*sb))
    258         return ret;
    259 
    260     return 0;
    261 }
    262 
    263 static ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
    264 {
    265     return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
    266             le32_to_cpu(es->s_blocks_count_lo);
    267 }
    268 
    269 static ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es)
    270 {
    271     return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
    272             le32_to_cpu(es->s_r_blocks_count_lo);
    273 }
    274 
    275 static int do_quota_with_shutdown_check(char *blk_device, char *fs_type,
    276                                         struct fstab_rec *rec, int *fs_stat)
    277 {
    278     int force_check = 0;
    279     if (!strcmp(fs_type, "ext4")) {
    280         /*
    281          * Some system images do not have tune2fs for licensing reasons
    282          * Detect these and skip reserve blocks.
    283          */
    284         if (access(TUNE2FS_BIN, X_OK)) {
    285             LERROR << "Not running " << TUNE2FS_BIN << " on "
    286                    << blk_device << " (executable not in system image)";
    287         } else {
    288             const char* arg1 = nullptr;
    289             const char* arg2 = nullptr;
    290             int status = 0;
    291             int ret = 0;
    292             android::base::unique_fd fd(
    293                 TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)));
    294             if (fd >= 0) {
    295                 struct ext4_super_block sb;
    296                 ret = read_super_block(fd, &sb);
    297                 if (ret < 0) {
    298                     PERROR << "Can't read '" << blk_device << "' super block";
    299                     return force_check;
    300                 }
    301                 if (sb.s_magic != EXT4_SUPER_MAGIC) {
    302                     LINFO << "Invalid ext4 magic:0x" << std::hex << sb.s_magic << "," << blk_device;
    303                     *fs_stat |= FS_STAT_EXT4_INVALID_MAGIC;
    304                     return 0;  // not a valid fs, tune2fs, fsck, and mount  will all fail.
    305                 }
    306                 *fs_stat |= FS_STAT_IS_EXT4;
    307                 LINFO << "superblock s_max_mnt_count:" << sb.s_max_mnt_count << "," << blk_device;
    308                 if (sb.s_max_mnt_count == 0xffff) {  // -1 (int16) in ext2, but uint16 in ext4
    309                     *fs_stat |= FS_STAT_NEW_IMAGE_VERSION;
    310                 }
    311                 if ((sb.s_feature_incompat & EXT4_FEATURE_INCOMPAT_RECOVER) != 0 ||
    312                     (sb.s_state & EXT4_VALID_FS) == 0) {
    313                     LINFO << __FUNCTION__ << "(): was not clealy shutdown, state flag:"
    314                           << std::hex << sb.s_state
    315                           << "incompat flag:" << std::hex << sb.s_feature_incompat;
    316                     force_check = 1;
    317                     *fs_stat |= FS_STAT_UNCLEAN_SHUTDOWN;
    318                 }
    319                 int has_quota = (sb.s_feature_ro_compat
    320                         & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0;
    321                 int want_quota = fs_mgr_is_quota(rec) != 0;
    322 
    323                 if (has_quota == want_quota) {
    324                     LINFO << "Requested quota status is match on " << blk_device;
    325                     return force_check;
    326                 } else if (want_quota) {
    327                     LINFO << "Enabling quota on " << blk_device;
    328                     arg1 = "-Oquota";
    329                     arg2 = "-Qusrquota,grpquota";
    330                     force_check = 1;
    331                     *fs_stat |= FS_STAT_QUOTA_ENABLED;
    332                 } else {
    333                     LINFO << "Disabling quota on " << blk_device;
    334                     arg1 = "-Q^usrquota,^grpquota";
    335                     arg2 = "-O^quota";
    336                 }
    337             } else {
    338                 PERROR << "Failed to open '" << blk_device << "'";
    339                 return force_check;
    340             }
    341 
    342             const char *tune2fs_argv[] = {
    343                 TUNE2FS_BIN,
    344                 arg1,
    345                 arg2,
    346                 blk_device,
    347             };
    348             ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv),
    349                                           const_cast<char **>(tune2fs_argv),
    350                                           &status, true, LOG_KLOG | LOG_FILE,
    351                                           true, NULL, NULL, 0);
    352             if (ret < 0) {
    353                 /* No need to check for error in fork, we can't really handle it now */
    354                 LERROR << "Failed trying to run " << TUNE2FS_BIN;
    355                 *fs_stat |= FS_STAT_TUNE2FS_FAILED;
    356             }
    357         }
    358     }
    359     return force_check;
    360 }
    361 
    362 static void do_reserved_size(char *blk_device, char *fs_type, struct fstab_rec *rec, int *fs_stat)
    363 {
    364     /* Check for the types of filesystems we know how to check */
    365     if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
    366         /*
    367          * Some system images do not have tune2fs for licensing reasons
    368          * Detect these and skip reserve blocks.
    369          */
    370         if (access(TUNE2FS_BIN, X_OK)) {
    371             LERROR << "Not running " << TUNE2FS_BIN << " on "
    372                    << blk_device << " (executable not in system image)";
    373         } else {
    374             LINFO << "Running " << TUNE2FS_BIN << " on " << blk_device;
    375 
    376             int status = 0;
    377             int ret = 0;
    378             unsigned long reserved_blocks = 0;
    379             android::base::unique_fd fd(
    380                 TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)));
    381             if (fd >= 0) {
    382                 struct ext4_super_block sb;
    383                 ret = read_super_block(fd, &sb);
    384                 if (ret < 0) {
    385                     PERROR << "Can't read '" << blk_device << "' super block";
    386                     return;
    387                 }
    388                 reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(&sb);
    389                 unsigned long reserved_threshold = ext4_blocks_count(&sb) * 0.02;
    390                 if (reserved_threshold < reserved_blocks) {
    391                     LWARNING << "Reserved blocks " << reserved_blocks
    392                              << " is too large";
    393                     reserved_blocks = reserved_threshold;
    394                 }
    395 
    396                 if (ext4_r_blocks_count(&sb) == reserved_blocks) {
    397                     LINFO << "Have reserved same blocks";
    398                     return;
    399                 }
    400             } else {
    401                 PERROR << "Failed to open '" << blk_device << "'";
    402                 return;
    403             }
    404 
    405             char buf[16] = {0};
    406             snprintf(buf, sizeof (buf), "-r %lu", reserved_blocks);
    407             const char *tune2fs_argv[] = {
    408                 TUNE2FS_BIN,
    409                 buf,
    410                 blk_device,
    411             };
    412 
    413             ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv),
    414                                           const_cast<char **>(tune2fs_argv),
    415                                           &status, true, LOG_KLOG | LOG_FILE,
    416                                           true, NULL, NULL, 0);
    417 
    418             if (ret < 0) {
    419                 /* No need to check for error in fork, we can't really handle it now */
    420                 LERROR << "Failed trying to run " << TUNE2FS_BIN;
    421                 *fs_stat |= FS_STAT_TUNE2FS_FAILED;
    422             }
    423         }
    424     }
    425 }
    426 
    427 static void remove_trailing_slashes(char *n)
    428 {
    429     int len;
    430 
    431     len = strlen(n) - 1;
    432     while ((*(n + len) == '/') && len) {
    433       *(n + len) = '\0';
    434       len--;
    435     }
    436 }
    437 
    438 /*
    439  * Mark the given block device as read-only, using the BLKROSET ioctl.
    440  * Return 0 on success, and -1 on error.
    441  */
    442 int fs_mgr_set_blk_ro(const char *blockdev)
    443 {
    444     int fd;
    445     int rc = -1;
    446     int ON = 1;
    447 
    448     fd = TEMP_FAILURE_RETRY(open(blockdev, O_RDONLY | O_CLOEXEC));
    449     if (fd < 0) {
    450         // should never happen
    451         return rc;
    452     }
    453 
    454     rc = ioctl(fd, BLKROSET, &ON);
    455     close(fd);
    456 
    457     return rc;
    458 }
    459 
    460 /*
    461  * __mount(): wrapper around the mount() system call which also
    462  * sets the underlying block device to read-only if the mount is read-only.
    463  * See "man 2 mount" for return values.
    464  */
    465 static int __mount(const char *source, const char *target, const struct fstab_rec *rec)
    466 {
    467     unsigned long mountflags = rec->flags;
    468     int ret;
    469     int save_errno;
    470 
    471     /* We need this because sometimes we have legacy symlinks
    472      * that are lingering around and need cleaning up.
    473      */
    474     struct stat info;
    475     if (!lstat(target, &info))
    476         if ((info.st_mode & S_IFMT) == S_IFLNK)
    477             unlink(target);
    478     mkdir(target, 0755);
    479     ret = mount(source, target, rec->fs_type, mountflags, rec->fs_options);
    480     save_errno = errno;
    481     LINFO << __FUNCTION__ << "(source=" << source << ",target="
    482           << target << ",type=" << rec->fs_type << ")=" << ret;
    483     if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
    484         fs_mgr_set_blk_ro(source);
    485     }
    486     errno = save_errno;
    487     return ret;
    488 }
    489 
    490 static int fs_match(const char *in1, const char *in2)
    491 {
    492     char *n1;
    493     char *n2;
    494     int ret;
    495 
    496     n1 = strdup(in1);
    497     n2 = strdup(in2);
    498 
    499     remove_trailing_slashes(n1);
    500     remove_trailing_slashes(n2);
    501 
    502     ret = !strcmp(n1, n2);
    503 
    504     free(n1);
    505     free(n2);
    506 
    507     return ret;
    508 }
    509 
    510 static int device_is_force_encrypted() {
    511     int ret = -1;
    512     char value[PROP_VALUE_MAX];
    513     ret = __system_property_get("ro.vold.forceencryption", value);
    514     if (ret < 0)
    515         return 0;
    516     return strcmp(value, "1") ? 0 : 1;
    517 }
    518 
    519 /*
    520  * Tries to mount any of the consecutive fstab entries that match
    521  * the mountpoint of the one given by fstab->recs[start_idx].
    522  *
    523  * end_idx: On return, will be the last rec that was looked at.
    524  * attempted_idx: On return, will indicate which fstab rec
    525  *     succeeded. In case of failure, it will be the start_idx.
    526  * Returns
    527  *   -1 on failure with errno set to match the 1st mount failure.
    528  *   0 on success.
    529  */
    530 static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_idx, int *attempted_idx)
    531 {
    532     int i;
    533     int mount_errno = 0;
    534     int mounted = 0;
    535 
    536     if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) {
    537       errno = EINVAL;
    538       if (end_idx) *end_idx = start_idx;
    539       if (attempted_idx) *attempted_idx = start_idx;
    540       return -1;
    541     }
    542 
    543     /* Hunt down an fstab entry for the same mount point that might succeed */
    544     for (i = start_idx;
    545          /* We required that fstab entries for the same mountpoint be consecutive */
    546          i < fstab->num_entries && !strcmp(fstab->recs[start_idx].mount_point, fstab->recs[i].mount_point);
    547          i++) {
    548             /*
    549              * Don't try to mount/encrypt the same mount point again.
    550              * Deal with alternate entries for the same point which are required to be all following
    551              * each other.
    552              */
    553             if (mounted) {
    554                 LERROR << __FUNCTION__ << "(): skipping fstab dup mountpoint="
    555                        << fstab->recs[i].mount_point << " rec[" << i
    556                        << "].fs_type=" << fstab->recs[i].fs_type
    557                        << " already mounted as "
    558                        << fstab->recs[*attempted_idx].fs_type;
    559                 continue;
    560             }
    561 
    562             int fs_stat = 0;
    563             int force_check = do_quota_with_shutdown_check(fstab->recs[i].blk_device,
    564                                                            fstab->recs[i].fs_type,
    565                                                            &fstab->recs[i], &fs_stat);
    566             if (fs_stat & FS_STAT_EXT4_INVALID_MAGIC) {
    567                 LERROR << __FUNCTION__ << "(): skipping mount, invalid ext4, mountpoint="
    568                        << fstab->recs[i].mount_point << " rec[" << i
    569                        << "].fs_type=" << fstab->recs[i].fs_type;
    570                 mount_errno = EINVAL;  // continue bootup for FDE
    571                 continue;
    572             }
    573             if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) {
    574                 check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
    575                          fstab->recs[i].mount_point, &fs_stat);
    576             }
    577 
    578             if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
    579                 do_reserved_size(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
    580                                  &fstab->recs[i], &fs_stat);
    581             }
    582 
    583             int retry_count = 2;
    584             while (retry_count-- > 0) {
    585                 if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point,
    586                              &fstab->recs[i])) {
    587                     *attempted_idx = i;
    588                     mounted = 1;
    589                     if (i != start_idx) {
    590                         LERROR << __FUNCTION__ << "(): Mounted " << fstab->recs[i].blk_device
    591                                << " on " << fstab->recs[i].mount_point
    592                                << " with fs_type=" << fstab->recs[i].fs_type << " instead of "
    593                                << fstab->recs[start_idx].fs_type;
    594                     }
    595                     fs_stat &= ~FS_STAT_FULL_MOUNT_FAILED;
    596                     mount_errno = 0;
    597                     break;
    598                 } else {
    599                     if (retry_count <= 0) break;  // run check_fs only once
    600                     fs_stat |= FS_STAT_FULL_MOUNT_FAILED;
    601                     /* back up the first errno for crypto decisions */
    602                     if (mount_errno == 0) {
    603                         mount_errno = errno;
    604                     }
    605                     // retry after fsck
    606                     check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
    607                              fstab->recs[i].mount_point, &fs_stat);
    608                 }
    609             }
    610             log_fs_stat(fstab->recs[i].blk_device, fs_stat);
    611     }
    612 
    613     /* Adjust i for the case where it was still withing the recs[] */
    614     if (i < fstab->num_entries) --i;
    615 
    616     *end_idx = i;
    617     if (!mounted) {
    618         *attempted_idx = start_idx;
    619         errno = mount_errno;
    620         return -1;
    621     }
    622     return 0;
    623 }
    624 
    625 static int translate_ext_labels(struct fstab_rec *rec)
    626 {
    627     DIR *blockdir = NULL;
    628     struct dirent *ent;
    629     char *label;
    630     size_t label_len;
    631     int ret = -1;
    632 
    633     if (strncmp(rec->blk_device, "LABEL=", 6))
    634         return 0;
    635 
    636     label = rec->blk_device + 6;
    637     label_len = strlen(label);
    638 
    639     if (label_len > 16) {
    640         LERROR << "FS label is longer than allowed by filesystem";
    641         goto out;
    642     }
    643 
    644 
    645     blockdir = opendir("/dev/block");
    646     if (!blockdir) {
    647         LERROR << "couldn't open /dev/block";
    648         goto out;
    649     }
    650 
    651     while ((ent = readdir(blockdir))) {
    652         int fd;
    653         char super_buf[1024];
    654         struct ext4_super_block *sb;
    655 
    656         if (ent->d_type != DT_BLK)
    657             continue;
    658 
    659         fd = openat(dirfd(blockdir), ent->d_name, O_RDONLY);
    660         if (fd < 0) {
    661             LERROR << "Cannot open block device /dev/block/" << ent->d_name;
    662             goto out;
    663         }
    664 
    665         if (TEMP_FAILURE_RETRY(lseek(fd, 1024, SEEK_SET)) < 0 ||
    666             TEMP_FAILURE_RETRY(read(fd, super_buf, 1024)) != 1024) {
    667             /* Probably a loopback device or something else without a readable
    668              * superblock.
    669              */
    670             close(fd);
    671             continue;
    672         }
    673 
    674         sb = (struct ext4_super_block *)super_buf;
    675         if (sb->s_magic != EXT4_SUPER_MAGIC) {
    676             LINFO << "/dev/block/" << ent->d_name << " not ext{234}";
    677             continue;
    678         }
    679 
    680         if (!strncmp(label, sb->s_volume_name, label_len)) {
    681             char *new_blk_device;
    682 
    683             if (asprintf(&new_blk_device, "/dev/block/%s", ent->d_name) < 0) {
    684                 LERROR << "Could not allocate block device string";
    685                 goto out;
    686             }
    687 
    688             LINFO << "resolved label " << rec->blk_device << " to "
    689                   << new_blk_device;
    690 
    691             free(rec->blk_device);
    692             rec->blk_device = new_blk_device;
    693             ret = 0;
    694             break;
    695         }
    696     }
    697 
    698 out:
    699     closedir(blockdir);
    700     return ret;
    701 }
    702 
    703 static bool needs_block_encryption(const struct fstab_rec* rec)
    704 {
    705     if (device_is_force_encrypted() && fs_mgr_is_encryptable(rec)) return true;
    706     if (rec->fs_mgr_flags & MF_FORCECRYPT) return true;
    707     if (rec->fs_mgr_flags & MF_CRYPT) {
    708         /* Check for existence of convert_fde breadcrumb file */
    709         char convert_fde_name[PATH_MAX];
    710         snprintf(convert_fde_name, sizeof(convert_fde_name),
    711                  "%s/misc/vold/convert_fde", rec->mount_point);
    712         if (access(convert_fde_name, F_OK) == 0) return true;
    713     }
    714     if (rec->fs_mgr_flags & MF_FORCEFDEORFBE) {
    715         /* Check for absence of convert_fbe breadcrumb file */
    716         char convert_fbe_name[PATH_MAX];
    717         snprintf(convert_fbe_name, sizeof(convert_fbe_name),
    718                  "%s/convert_fbe", rec->mount_point);
    719         if (access(convert_fbe_name, F_OK) != 0) return true;
    720     }
    721     return false;
    722 }
    723 
    724 // Check to see if a mountable volume has encryption requirements
    725 static int handle_encryptable(const struct fstab_rec* rec)
    726 {
    727     /* If this is block encryptable, need to trigger encryption */
    728     if (needs_block_encryption(rec)) {
    729         if (umount(rec->mount_point) == 0) {
    730             return FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION;
    731         } else {
    732             PWARNING << "Could not umount " << rec->mount_point
    733                      << " - allow continue unencrypted";
    734             return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
    735         }
    736     } else if (rec->fs_mgr_flags & (MF_FILEENCRYPTION | MF_FORCEFDEORFBE)) {
    737         // Deal with file level encryption
    738         LINFO << rec->mount_point << " is file encrypted";
    739         return FS_MGR_MNTALL_DEV_FILE_ENCRYPTED;
    740     } else if (fs_mgr_is_encryptable(rec)) {
    741         return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
    742     } else {
    743         return FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
    744     }
    745 }
    746 
    747 // TODO: add ueventd notifiers if they don't exist.
    748 // This is just doing a wait_for_device for maximum of 1s
    749 int fs_mgr_test_access(const char *device) {
    750     int tries = 25;
    751     while (tries--) {
    752         if (!access(device, F_OK) || errno != ENOENT) {
    753             return 0;
    754         }
    755         usleep(40 * 1000);
    756     }
    757     return -1;
    758 }
    759 
    760 bool is_device_secure() {
    761     int ret = -1;
    762     char value[PROP_VALUE_MAX];
    763     ret = __system_property_get("ro.secure", value);
    764     if (ret == 0) {
    765 #ifdef ALLOW_SKIP_SECURE_CHECK
    766         // Allow eng builds to skip this check if the property
    767         // is not readable (happens during early mount)
    768         return false;
    769 #else
    770         // If error and not an 'eng' build, we want to fail secure.
    771         return true;
    772 #endif
    773     }
    774     return strcmp(value, "0") ? true : false;
    775 }
    776 
    777 /* When multiple fstab records share the same mount_point, it will
    778  * try to mount each one in turn, and ignore any duplicates after a
    779  * first successful mount.
    780  * Returns -1 on error, and  FS_MGR_MNTALL_* otherwise.
    781  */
    782 int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
    783 {
    784     int i = 0;
    785     int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
    786     int error_count = 0;
    787     int mret = -1;
    788     int mount_errno = 0;
    789     int attempted_idx = -1;
    790     FsManagerAvbUniquePtr avb_handle(nullptr);
    791 
    792     if (!fstab) {
    793         return -1;
    794     }
    795 
    796     for (i = 0; i < fstab->num_entries; i++) {
    797         /* Don't mount entries that are managed by vold or not for the mount mode*/
    798         if ((fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) ||
    799              ((mount_mode == MOUNT_MODE_LATE) && !fs_mgr_is_latemount(&fstab->recs[i])) ||
    800              ((mount_mode == MOUNT_MODE_EARLY) && fs_mgr_is_latemount(&fstab->recs[i]))) {
    801             continue;
    802         }
    803 
    804         /* Skip swap and raw partition entries such as boot, recovery, etc */
    805         if (!strcmp(fstab->recs[i].fs_type, "swap") ||
    806             !strcmp(fstab->recs[i].fs_type, "emmc") ||
    807             !strcmp(fstab->recs[i].fs_type, "mtd")) {
    808             continue;
    809         }
    810 
    811         /* Skip mounting the root partition, as it will already have been mounted */
    812         if (!strcmp(fstab->recs[i].mount_point, "/")) {
    813             if ((fstab->recs[i].fs_mgr_flags & MS_RDONLY) != 0) {
    814                 fs_mgr_set_blk_ro(fstab->recs[i].blk_device);
    815             }
    816             continue;
    817         }
    818 
    819         /* Translate LABEL= file system labels into block devices */
    820         if (!strcmp(fstab->recs[i].fs_type, "ext2") ||
    821             !strcmp(fstab->recs[i].fs_type, "ext3") ||
    822             !strcmp(fstab->recs[i].fs_type, "ext4")) {
    823             int tret = translate_ext_labels(&fstab->recs[i]);
    824             if (tret < 0) {
    825                 LERROR << "Could not translate label to block device";
    826                 continue;
    827             }
    828         }
    829 
    830         if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
    831             wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
    832         }
    833 
    834         if (fstab->recs[i].fs_mgr_flags & MF_AVB) {
    835             if (!avb_handle) {
    836                 avb_handle = FsManagerAvbHandle::Open(*fstab);
    837                 if (!avb_handle) {
    838                     LERROR << "Failed to open FsManagerAvbHandle";
    839                     return -1;
    840                 }
    841             }
    842             if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) {
    843                 LERROR << "Failed to set up AVB on partition: "
    844                        << fstab->recs[i].mount_point << ", skipping!";
    845                 /* Skips mounting the device. */
    846                 continue;
    847             }
    848         } else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && is_device_secure()) {
    849             int rc = fs_mgr_setup_verity(&fstab->recs[i], true);
    850             if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
    851                 LINFO << "Verity disabled";
    852             } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
    853                 LERROR << "Could not set up verified partition, skipping!";
    854                 continue;
    855             }
    856         }
    857 
    858         int last_idx_inspected;
    859         int top_idx = i;
    860 
    861         mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
    862         i = last_idx_inspected;
    863         mount_errno = errno;
    864 
    865         /* Deal with encryptability. */
    866         if (!mret) {
    867             int status = handle_encryptable(&fstab->recs[attempted_idx]);
    868 
    869             if (status == FS_MGR_MNTALL_FAIL) {
    870                 /* Fatal error - no point continuing */
    871                 return status;
    872             }
    873 
    874             if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
    875                 if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
    876                     // Log and continue
    877                     LERROR << "Only one encryptable/encrypted partition supported";
    878                 }
    879                 encryptable = status;
    880             }
    881 
    882             /* Success!  Go get the next one */
    883             continue;
    884         }
    885 
    886         /* mount(2) returned an error, handle the encryptable/formattable case */
    887         bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
    888         bool crypt_footer = false;
    889         if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
    890             fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) {
    891             /* top_idx and attempted_idx point at the same partition, but sometimes
    892              * at two different lines in the fstab.  Use the top one for formatting
    893              * as that is the preferred one.
    894              */
    895             LERROR << __FUNCTION__ << "(): " << fstab->recs[top_idx].blk_device
    896                    << " is wiped and " << fstab->recs[top_idx].mount_point
    897                    << " " << fstab->recs[top_idx].fs_type
    898                    << " is formattable. Format it.";
    899             if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
    900                 strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
    901                 int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY);
    902                 if (fd >= 0) {
    903                     LINFO << __FUNCTION__ << "(): also wipe "
    904                           << fstab->recs[top_idx].key_loc;
    905                     wipe_block_device(fd, get_file_size(fd));
    906                     close(fd);
    907                 } else {
    908                     PERROR << __FUNCTION__ << "(): "
    909                            << fstab->recs[top_idx].key_loc << " wouldn't open";
    910                 }
    911             } else if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
    912                 !strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
    913                 crypt_footer = true;
    914             }
    915             if (fs_mgr_do_format(&fstab->recs[top_idx], crypt_footer) == 0) {
    916                 /* Let's replay the mount actions. */
    917                 i = top_idx - 1;
    918                 continue;
    919             } else {
    920                 LERROR << __FUNCTION__ << "(): Format failed. "
    921                        << "Suggest recovery...";
    922                 encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
    923                 continue;
    924             }
    925         }
    926         if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
    927             fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
    928             if (wiped) {
    929                 LERROR << __FUNCTION__ << "(): "
    930                        << fstab->recs[attempted_idx].blk_device
    931                        << " is wiped and "
    932                        << fstab->recs[attempted_idx].mount_point << " "
    933                        << fstab->recs[attempted_idx].fs_type
    934                        << " is encryptable. Suggest recovery...";
    935                 encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
    936                 continue;
    937             } else {
    938                 /* Need to mount a tmpfs at this mountpoint for now, and set
    939                  * properties that vold will query later for decrypting
    940                  */
    941                 LERROR << __FUNCTION__ << "(): possibly an encryptable blkdev "
    942                        << fstab->recs[attempted_idx].blk_device
    943                        << " for mount " << fstab->recs[attempted_idx].mount_point
    944                        << " type " << fstab->recs[attempted_idx].fs_type;
    945                 if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
    946                     ++error_count;
    947                     continue;
    948                 }
    949             }
    950             encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
    951         } else {
    952             // fs_options might be null so we cannot use PERROR << directly.
    953             // Use StringPrintf to output "(null)" instead.
    954             if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) {
    955                 PERROR << android::base::StringPrintf(
    956                     "Ignoring failure to mount an un-encryptable or wiped "
    957                     "partition on %s at %s options: %s",
    958                     fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
    959                     fstab->recs[attempted_idx].fs_options);
    960             } else {
    961                 PERROR << android::base::StringPrintf(
    962                     "Failed to mount an un-encryptable or wiped partition "
    963                     "on %s at %s options: %s",
    964                     fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
    965                     fstab->recs[attempted_idx].fs_options);
    966                 ++error_count;
    967             }
    968             continue;
    969         }
    970     }
    971 
    972     if (error_count) {
    973         return -1;
    974     } else {
    975         return encryptable;
    976     }
    977 }
    978 
    979 /* wrapper to __mount() and expects a fully prepared fstab_rec,
    980  * unlike fs_mgr_do_mount which does more things with avb / verity
    981  * etc.
    982  */
    983 int fs_mgr_do_mount_one(struct fstab_rec *rec)
    984 {
    985     if (!rec) {
    986         return FS_MGR_DOMNT_FAILED;
    987     }
    988 
    989     int ret = __mount(rec->blk_device, rec->mount_point, rec);
    990     if (ret) {
    991       ret = (errno == EBUSY) ? FS_MGR_DOMNT_BUSY : FS_MGR_DOMNT_FAILED;
    992     }
    993 
    994     return ret;
    995 }
    996 
    997 /* If tmp_mount_point is non-null, mount the filesystem there.  This is for the
    998  * tmp mount we do to check the user password
    999  * If multiple fstab entries are to be mounted on "n_name", it will try to mount each one
   1000  * in turn, and stop on 1st success, or no more match.
   1001  */
   1002 int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
   1003                     char *tmp_mount_point)
   1004 {
   1005     int i = 0;
   1006     int ret = FS_MGR_DOMNT_FAILED;
   1007     int mount_errors = 0;
   1008     int first_mount_errno = 0;
   1009     char *m;
   1010     FsManagerAvbUniquePtr avb_handle(nullptr);
   1011 
   1012     if (!fstab) {
   1013         return ret;
   1014     }
   1015 
   1016     for (i = 0; i < fstab->num_entries; i++) {
   1017         if (!fs_match(fstab->recs[i].mount_point, n_name)) {
   1018             continue;
   1019         }
   1020 
   1021         /* We found our match */
   1022         /* If this swap or a raw partition, report an error */
   1023         if (!strcmp(fstab->recs[i].fs_type, "swap") ||
   1024             !strcmp(fstab->recs[i].fs_type, "emmc") ||
   1025             !strcmp(fstab->recs[i].fs_type, "mtd")) {
   1026             LERROR << "Cannot mount filesystem of type "
   1027                    << fstab->recs[i].fs_type << " on " << n_blk_device;
   1028             goto out;
   1029         }
   1030 
   1031         /* First check the filesystem if requested */
   1032         if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
   1033             wait_for_file(n_blk_device, WAIT_TIMEOUT);
   1034         }
   1035 
   1036         int fs_stat = 0;
   1037         int force_check = do_quota_with_shutdown_check(n_blk_device, fstab->recs[i].fs_type,
   1038                                                        &fstab->recs[i], &fs_stat);
   1039 
   1040         if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) {
   1041             check_fs(n_blk_device, fstab->recs[i].fs_type,
   1042                      fstab->recs[i].mount_point, &fs_stat);
   1043         }
   1044 
   1045         if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
   1046             do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i], &fs_stat);
   1047         }
   1048 
   1049         if (fstab->recs[i].fs_mgr_flags & MF_AVB) {
   1050             if (!avb_handle) {
   1051                 avb_handle = FsManagerAvbHandle::Open(*fstab);
   1052                 if (!avb_handle) {
   1053                     LERROR << "Failed to open FsManagerAvbHandle";
   1054                     return -1;
   1055                 }
   1056             }
   1057             if (!avb_handle->SetUpAvb(&fstab->recs[i], true /* wait_for_verity_dev */)) {
   1058                 LERROR << "Failed to set up AVB on partition: "
   1059                        << fstab->recs[i].mount_point << ", skipping!";
   1060                 /* Skips mounting the device. */
   1061                 continue;
   1062             }
   1063         } else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && is_device_secure()) {
   1064             int rc = fs_mgr_setup_verity(&fstab->recs[i], true);
   1065             if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
   1066                 LINFO << "Verity disabled";
   1067             } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
   1068                 LERROR << "Could not set up verified partition, skipping!";
   1069                 continue;
   1070             }
   1071         }
   1072 
   1073         /* Now mount it where requested */
   1074         if (tmp_mount_point) {
   1075             m = tmp_mount_point;
   1076         } else {
   1077             m = fstab->recs[i].mount_point;
   1078         }
   1079         int retry_count = 2;
   1080         while (retry_count-- > 0) {
   1081             if (!__mount(n_blk_device, m, &fstab->recs[i])) {
   1082                 ret = 0;
   1083                 fs_stat &= ~FS_STAT_FULL_MOUNT_FAILED;
   1084                 goto out;
   1085             } else {
   1086                 if (retry_count <= 0) break;  // run check_fs only once
   1087                 if (!first_mount_errno) first_mount_errno = errno;
   1088                 mount_errors++;
   1089                 fs_stat |= FS_STAT_FULL_MOUNT_FAILED;
   1090                 // try again after fsck
   1091                 check_fs(n_blk_device, fstab->recs[i].fs_type, fstab->recs[i].mount_point, &fs_stat);
   1092             }
   1093         }
   1094         log_fs_stat(fstab->recs[i].blk_device, fs_stat);
   1095     }
   1096     if (mount_errors) {
   1097         PERROR << "Cannot mount filesystem on " << n_blk_device
   1098                << " at " << m;
   1099         if (first_mount_errno == EBUSY) {
   1100             ret = FS_MGR_DOMNT_BUSY;
   1101         } else {
   1102             ret = FS_MGR_DOMNT_FAILED;
   1103         }
   1104     } else {
   1105         /* We didn't find a match, say so and return an error */
   1106         LERROR << "Cannot find mount point " << fstab->recs[i].mount_point
   1107                << " in fstab";
   1108     }
   1109 
   1110 out:
   1111     return ret;
   1112 }
   1113 
   1114 /*
   1115  * mount a tmpfs filesystem at the given point.
   1116  * return 0 on success, non-zero on failure.
   1117  */
   1118 int fs_mgr_do_tmpfs_mount(const char *n_name)
   1119 {
   1120     int ret;
   1121 
   1122     ret = mount("tmpfs", n_name, "tmpfs",
   1123                 MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS);
   1124     if (ret < 0) {
   1125         LERROR << "Cannot mount tmpfs filesystem at " << n_name;
   1126         return -1;
   1127     }
   1128 
   1129     /* Success */
   1130     return 0;
   1131 }
   1132 
   1133 int fs_mgr_unmount_all(struct fstab *fstab)
   1134 {
   1135     int i = 0;
   1136     int ret = 0;
   1137 
   1138     if (!fstab) {
   1139         return -1;
   1140     }
   1141 
   1142     while (fstab->recs[i].blk_device) {
   1143         if (umount(fstab->recs[i].mount_point)) {
   1144             LERROR << "Cannot unmount filesystem at "
   1145                    << fstab->recs[i].mount_point;
   1146             ret = -1;
   1147         }
   1148         i++;
   1149     }
   1150 
   1151     return ret;
   1152 }
   1153 
   1154 /* This must be called after mount_all, because the mkswap command needs to be
   1155  * available.
   1156  */
   1157 int fs_mgr_swapon_all(struct fstab *fstab)
   1158 {
   1159     int i = 0;
   1160     int flags = 0;
   1161     int err = 0;
   1162     int ret = 0;
   1163     int status;
   1164     const char *mkswap_argv[2] = {
   1165         MKSWAP_BIN,
   1166         nullptr
   1167     };
   1168 
   1169     if (!fstab) {
   1170         return -1;
   1171     }
   1172 
   1173     for (i = 0; i < fstab->num_entries; i++) {
   1174         /* Skip non-swap entries */
   1175         if (strcmp(fstab->recs[i].fs_type, "swap")) {
   1176             continue;
   1177         }
   1178 
   1179         if (fstab->recs[i].zram_size > 0) {
   1180             /* A zram_size was specified, so we need to configure the
   1181              * device.  There is no point in having multiple zram devices
   1182              * on a system (all the memory comes from the same pool) so
   1183              * we can assume the device number is 0.
   1184              */
   1185             FILE *zram_fp;
   1186             FILE *zram_mcs_fp;
   1187 
   1188             if (fstab->recs[i].max_comp_streams >= 0) {
   1189                zram_mcs_fp = fopen(ZRAM_CONF_MCS, "r+");
   1190               if (zram_mcs_fp == NULL) {
   1191                 LERROR << "Unable to open zram conf comp device "
   1192                        << ZRAM_CONF_MCS;
   1193                 ret = -1;
   1194                 continue;
   1195               }
   1196               fprintf(zram_mcs_fp, "%d\n", fstab->recs[i].max_comp_streams);
   1197               fclose(zram_mcs_fp);
   1198             }
   1199 
   1200             zram_fp = fopen(ZRAM_CONF_DEV, "r+");
   1201             if (zram_fp == NULL) {
   1202                 LERROR << "Unable to open zram conf device " << ZRAM_CONF_DEV;
   1203                 ret = -1;
   1204                 continue;
   1205             }
   1206             fprintf(zram_fp, "%d\n", fstab->recs[i].zram_size);
   1207             fclose(zram_fp);
   1208         }
   1209 
   1210         if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
   1211             wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
   1212         }
   1213 
   1214         /* Initialize the swap area */
   1215         mkswap_argv[1] = fstab->recs[i].blk_device;
   1216         err = android_fork_execvp_ext(ARRAY_SIZE(mkswap_argv),
   1217                                       const_cast<char **>(mkswap_argv),
   1218                                       &status, true, LOG_KLOG, false, NULL,
   1219                                       NULL, 0);
   1220         if (err) {
   1221             LERROR << "mkswap failed for " << fstab->recs[i].blk_device;
   1222             ret = -1;
   1223             continue;
   1224         }
   1225 
   1226         /* If -1, then no priority was specified in fstab, so don't set
   1227          * SWAP_FLAG_PREFER or encode the priority */
   1228         if (fstab->recs[i].swap_prio >= 0) {
   1229             flags = (fstab->recs[i].swap_prio << SWAP_FLAG_PRIO_SHIFT) &
   1230                     SWAP_FLAG_PRIO_MASK;
   1231             flags |= SWAP_FLAG_PREFER;
   1232         } else {
   1233             flags = 0;
   1234         }
   1235         err = swapon(fstab->recs[i].blk_device, flags);
   1236         if (err) {
   1237             LERROR << "swapon failed for " << fstab->recs[i].blk_device;
   1238             ret = -1;
   1239         }
   1240     }
   1241 
   1242     return ret;
   1243 }
   1244 
   1245 /*
   1246  * key_loc must be at least PROPERTY_VALUE_MAX bytes long
   1247  *
   1248  * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long
   1249  */
   1250 int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_device, int size)
   1251 {
   1252     int i = 0;
   1253 
   1254     if (!fstab) {
   1255         return -1;
   1256     }
   1257     /* Initialize return values to null strings */
   1258     if (key_loc) {
   1259         *key_loc = '\0';
   1260     }
   1261     if (real_blk_device) {
   1262         *real_blk_device = '\0';
   1263     }
   1264 
   1265     /* Look for the encryptable partition to find the data */
   1266     for (i = 0; i < fstab->num_entries; i++) {
   1267         /* Don't deal with vold managed enryptable partitions here */
   1268         if (fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) {
   1269             continue;
   1270         }
   1271         if (!(fstab->recs[i].fs_mgr_flags
   1272               & (MF_CRYPT | MF_FORCECRYPT | MF_FORCEFDEORFBE))) {
   1273             continue;
   1274         }
   1275 
   1276         /* We found a match */
   1277         if (key_loc) {
   1278             strlcpy(key_loc, fstab->recs[i].key_loc, size);
   1279         }
   1280         if (real_blk_device) {
   1281             strlcpy(real_blk_device, fstab->recs[i].blk_device, size);
   1282         }
   1283         break;
   1284     }
   1285 
   1286     return 0;
   1287 }
   1288 
   1289 bool fs_mgr_load_verity_state(int* mode) {
   1290     /* return the default mode, unless any of the verified partitions are in
   1291      * logging mode, in which case return that */
   1292     *mode = VERITY_MODE_DEFAULT;
   1293 
   1294     std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
   1295                                                                fs_mgr_free_fstab);
   1296     if (!fstab) {
   1297         LERROR << "Failed to read default fstab";
   1298         return false;
   1299     }
   1300 
   1301     for (int i = 0; i < fstab->num_entries; i++) {
   1302         if (fs_mgr_is_avb(&fstab->recs[i])) {
   1303             *mode = VERITY_MODE_RESTART;  // avb only supports restart mode.
   1304             break;
   1305         } else if (!fs_mgr_is_verified(&fstab->recs[i])) {
   1306             continue;
   1307         }
   1308 
   1309         int current;
   1310         if (load_verity_state(&fstab->recs[i], &current) < 0) {
   1311             continue;
   1312         }
   1313         if (current != VERITY_MODE_DEFAULT) {
   1314             *mode = current;
   1315             break;
   1316         }
   1317     }
   1318 
   1319     return true;
   1320 }
   1321 
   1322 bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback) {
   1323     if (!callback) {
   1324         return false;
   1325     }
   1326 
   1327     int mode;
   1328     if (!fs_mgr_load_verity_state(&mode)) {
   1329         return false;
   1330     }
   1331 
   1332     android::base::unique_fd fd(TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC)));
   1333     if (fd == -1) {
   1334         PERROR << "Error opening device mapper";
   1335         return false;
   1336     }
   1337 
   1338     std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
   1339                                                                fs_mgr_free_fstab);
   1340     if (!fstab) {
   1341         LERROR << "Failed to read default fstab";
   1342         return false;
   1343     }
   1344 
   1345     alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
   1346     struct dm_ioctl* io = (struct dm_ioctl*)buffer;
   1347     bool system_root = android::base::GetProperty("ro.build.system_root_image", "") == "true";
   1348 
   1349     for (int i = 0; i < fstab->num_entries; i++) {
   1350         if (!fs_mgr_is_verified(&fstab->recs[i]) && !fs_mgr_is_avb(&fstab->recs[i])) {
   1351             continue;
   1352         }
   1353 
   1354         std::string mount_point;
   1355         if (system_root && !strcmp(fstab->recs[i].mount_point, "/")) {
   1356             // In AVB, the dm device name is vroot instead of system.
   1357             mount_point = fs_mgr_is_avb(&fstab->recs[i]) ? "vroot" : "system";
   1358         } else {
   1359             mount_point = basename(fstab->recs[i].mount_point);
   1360         }
   1361 
   1362         fs_mgr_verity_ioctl_init(io, mount_point, 0);
   1363 
   1364         const char* status;
   1365         if (ioctl(fd, DM_TABLE_STATUS, io)) {
   1366             if (fstab->recs[i].fs_mgr_flags & MF_VERIFYATBOOT) {
   1367                 status = "V";
   1368             } else {
   1369                 PERROR << "Failed to query DM_TABLE_STATUS for " << mount_point.c_str();
   1370                 continue;
   1371             }
   1372         }
   1373 
   1374         status = &buffer[io->data_start + sizeof(struct dm_target_spec)];
   1375 
   1376         // To be consistent in vboot 1.0 and vboot 2.0 (AVB), change the mount_point
   1377         // back to 'system' for the callback. So it has property [partition.system.verified]
   1378         // instead of [partition.vroot.verified].
   1379         if (mount_point == "vroot") mount_point = "system";
   1380         if (*status == 'C' || *status == 'V') {
   1381             callback(&fstab->recs[i], mount_point.c_str(), mode, *status);
   1382         }
   1383     }
   1384 
   1385     return true;
   1386 }
   1387