blob: be84e8a5108a807ba149f199d87c907bb46eae31 [file] [log] [blame]
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001/*
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
Mattias Nissler097b6bb2016-03-31 16:32:09 +020017#include <ctype.h>
18#include <dirent.h>
19#include <errno.h>
20#include <fcntl.h>
21#include <libgen.h>
Ken Sumrallc1bf8962012-01-06 19:09:42 -080022#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
liminghao9a0fd1d2016-07-22 11:48:14 +080025#include <sys/ioctl.h>
Ken Sumrallc1bf8962012-01-06 19:09:42 -080026#include <sys/mount.h>
27#include <sys/stat.h>
Mattias Nissler097b6bb2016-03-31 16:32:09 +020028#include <sys/swap.h>
Ken Sumrallc1bf8962012-01-06 19:09:42 -080029#include <sys/types.h>
30#include <sys/wait.h>
Ken Sumrallc1bf8962012-01-06 19:09:42 -080031#include <time.h>
Mattias Nissler097b6bb2016-03-31 16:32:09 +020032#include <unistd.h>
Ken Sumrallc1bf8962012-01-06 19:09:42 -080033
bowgotsaicea7ea72017-01-16 21:49:49 +080034#include <android-base/unique_fd.h>
JP Abgrall4bb7bba2014-06-19 22:12:20 -070035#include <cutils/android_reboot.h>
Ken Sumrallc1bf8962012-01-06 19:09:42 -080036#include <cutils/partition_utils.h>
37#include <cutils/properties.h>
Tao Bao6d881d62016-10-05 17:53:30 -070038#include <ext4_utils/ext4.h>
39#include <ext4_utils/ext4_crypt_init_extensions.h>
40#include <ext4_utils/ext4_sb.h>
41#include <ext4_utils/ext4_utils.h>
42#include <ext4_utils/wipe.h>
liminghao9a0fd1d2016-07-22 11:48:14 +080043#include <linux/fs.h>
Mattias Nissler097b6bb2016-03-31 16:32:09 +020044#include <linux/loop.h>
Ken Sumrallbf021b42013-03-19 19:38:44 -070045#include <logwrap/logwrap.h>
Mattias Nissler097b6bb2016-03-31 16:32:09 +020046#include <private/android_filesystem_config.h>
Mark Salyzyne528be52016-03-29 14:25:11 -070047#include <private/android_logger.h>
Geremy Condra3ad3d1c2013-02-22 18:11:41 -080048
Ken Sumrallc1bf8962012-01-06 19:09:42 -080049#include "fs_mgr_priv.h"
bowgotsaib51722b2017-01-11 22:21:38 +080050#include "fs_mgr_priv_avb.h"
Geremy Condra3ad3d1c2013-02-22 18:11:41 -080051#include "fs_mgr_priv_verity.h"
Ken Sumrallc1bf8962012-01-06 19:09:42 -080052
53#define KEY_LOC_PROP "ro.crypto.keyfile.userdata"
54#define KEY_IN_FOOTER "footer"
55
56#define E2FSCK_BIN "/system/bin/e2fsck"
liminghao9a0fd1d2016-07-22 11:48:14 +080057#define F2FS_FSCK_BIN "/system/bin/fsck.f2fs"
Ken Sumrall5bc31a22013-07-08 19:11:55 -070058#define MKSWAP_BIN "/system/bin/mkswap"
liminghao9a0fd1d2016-07-22 11:48:14 +080059#define TUNE2FS_BIN "/system/bin/tune2fs"
Ken Sumrall5bc31a22013-07-08 19:11:55 -070060
Ken Sumrall4eaf9052013-09-18 17:49:21 -070061#define FSCK_LOG_FILE "/dev/fscklogs/log"
62
Ken Sumrall5bc31a22013-07-08 19:11:55 -070063#define ZRAM_CONF_DEV "/sys/block/zram0/disksize"
Peter Enderborg4d217f02016-08-26 15:09:35 +020064#define ZRAM_CONF_MCS "/sys/block/zram0/max_comp_streams"
Ken Sumrallc1bf8962012-01-06 19:09:42 -080065
Ken Sumrallbf021b42013-03-19 19:38:44 -070066#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
67
Ken Sumrallc1bf8962012-01-06 19:09:42 -080068/*
69 * gettime() - returns the time in seconds of the system's monotonic clock or
70 * zero on error.
71 */
72static time_t gettime(void)
73{
74 struct timespec ts;
75 int ret;
76
77 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
78 if (ret < 0) {
bowgotsai47878de2017-01-23 14:04:34 +080079 PERROR << "clock_gettime(CLOCK_MONOTONIC) failed";
Ken Sumrallc1bf8962012-01-06 19:09:42 -080080 return 0;
81 }
82
83 return ts.tv_sec;
84}
85
86static int wait_for_file(const char *filename, int timeout)
87{
88 struct stat info;
89 time_t timeout_time = gettime() + timeout;
90 int ret = -1;
91
92 while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0))
93 usleep(10000);
94
95 return ret;
96}
97
bowgotsaicea7ea72017-01-16 21:49:49 +080098static void check_fs(const char *blk_device, char *fs_type, char *target)
Ken Sumrallc1bf8962012-01-06 19:09:42 -080099{
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800100 int status;
Ken Sumrall5dc5bfe2012-07-23 19:34:00 -0700101 int ret;
102 long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
Oreste Salerno6ed84c92015-05-20 17:01:39 +0000103 char tmpmnt_opts[64] = "errors=remount-ro";
bowgotsaicea7ea72017-01-16 21:49:49 +0800104 const char *e2fsck_argv[] = {
Ken Sumrallbf021b42013-03-19 19:38:44 -0700105 E2FSCK_BIN,
Keun-young Park22e81992017-01-09 16:39:49 -0800106#ifndef TARGET_USES_MKE2FS // "-f" only for old ext4 generation tool
Robb Glasser3fb176c2016-04-05 18:43:37 +0000107 "-f",
Keun-young Park22e81992017-01-09 16:39:49 -0800108#endif
Ken Sumrallbf021b42013-03-19 19:38:44 -0700109 "-y",
110 blk_device
111 };
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800112
113 /* Check for the types of filesystems we know how to check */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800114 if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
Ken Sumrall5dc5bfe2012-07-23 19:34:00 -0700115 /*
116 * First try to mount and unmount the filesystem. We do this because
117 * the kernel is more efficient than e2fsck in running the journal and
118 * processing orphaned inodes, and on at least one device with a
119 * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes
120 * to do what the kernel does in about a second.
121 *
122 * After mounting and unmounting the filesystem, run e2fsck, and if an
123 * error is recorded in the filesystem superblock, e2fsck will do a full
124 * check. Otherwise, it does nothing. If the kernel cannot mount the
125 * filesytsem due to an error, e2fsck is still run to do a full check
126 * fix the filesystem.
127 */
Elliott Hughes5e7dd442015-04-24 11:05:48 -0700128 errno = 0;
Oreste Salerno6ed84c92015-05-20 17:01:39 +0000129 if (!strcmp(fs_type, "ext4")) {
130 // This option is only valid with ext4
131 strlcat(tmpmnt_opts, ",nomblk_io_submit", sizeof(tmpmnt_opts));
132 }
Ken Sumrallab6b8522013-02-13 12:58:40 -0800133 ret = mount(blk_device, target, fs_type, tmpmnt_flags, tmpmnt_opts);
bowgotsai47878de2017-01-23 14:04:34 +0800134 PINFO << __FUNCTION__ << "(): mount(" << blk_device << "," << target
135 << "," << fs_type << ")=" << ret;
Ken Sumrallab6b8522013-02-13 12:58:40 -0800136 if (!ret) {
Nick Kralevich7294eb62015-02-05 16:02:42 -0800137 int i;
138 for (i = 0; i < 5; i++) {
139 // Try to umount 5 times before continuing on.
140 // Should we try rebooting if all attempts fail?
141 int result = umount(target);
142 if (result == 0) {
bowgotsai47878de2017-01-23 14:04:34 +0800143 LINFO << __FUNCTION__ << "(): unmount(" << target
144 << ") succeeded";
Nick Kralevich7294eb62015-02-05 16:02:42 -0800145 break;
146 }
bowgotsai47878de2017-01-23 14:04:34 +0800147 PERROR << __FUNCTION__ << "(): umount(" << target << ")="
148 << result;
Nick Kralevich7294eb62015-02-05 16:02:42 -0800149 sleep(1);
150 }
Ken Sumrall5dc5bfe2012-07-23 19:34:00 -0700151 }
152
David 'Digit' Turner28483d72014-02-17 11:14:44 +0100153 /*
154 * Some system images do not have e2fsck for licensing reasons
155 * (e.g. recent SDK system images). Detect these and skip the check.
156 */
157 if (access(E2FSCK_BIN, X_OK)) {
bowgotsai47878de2017-01-23 14:04:34 +0800158 LINFO << "Not running " << E2FSCK_BIN << " on " << blk_device
159 << " (executable not in system image)";
David 'Digit' Turner28483d72014-02-17 11:14:44 +0100160 } else {
bowgotsai47878de2017-01-23 14:04:34 +0800161 LINFO << "Running " << E2FSCK_BIN << " on " << blk_device;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800162
bowgotsaicea7ea72017-01-16 21:49:49 +0800163 ret = android_fork_execvp_ext(ARRAY_SIZE(e2fsck_argv),
164 const_cast<char **>(e2fsck_argv),
Yusuke Satod81c3c62015-08-14 01:22:53 -0700165 &status, true, LOG_KLOG | LOG_FILE,
bowgotsaicea7ea72017-01-16 21:49:49 +0800166 true,
167 const_cast<char *>(FSCK_LOG_FILE),
168 NULL, 0);
Ken Sumrallbf021b42013-03-19 19:38:44 -0700169
David 'Digit' Turner28483d72014-02-17 11:14:44 +0100170 if (ret < 0) {
171 /* No need to check for error in fork, we can't really handle it now */
bowgotsai47878de2017-01-23 14:04:34 +0800172 LERROR << "Failed trying to run " << E2FSCK_BIN;
David 'Digit' Turner28483d72014-02-17 11:14:44 +0100173 }
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800174 }
JP Abgrall12351582014-06-17 17:01:14 -0700175 } else if (!strcmp(fs_type, "f2fs")) {
bowgotsaicea7ea72017-01-16 21:49:49 +0800176 const char *f2fs_fsck_argv[] = {
JP Abgrall12351582014-06-17 17:01:14 -0700177 F2FS_FSCK_BIN,
Yusuke Sato0df08272015-07-08 14:57:07 -0700178 "-a",
JP Abgrall12351582014-06-17 17:01:14 -0700179 blk_device
180 };
bowgotsai47878de2017-01-23 14:04:34 +0800181 LINFO << "Running " << F2FS_FSCK_BIN << " -a " << blk_device;
JP Abgrall12351582014-06-17 17:01:14 -0700182
bowgotsaicea7ea72017-01-16 21:49:49 +0800183 ret = android_fork_execvp_ext(ARRAY_SIZE(f2fs_fsck_argv),
184 const_cast<char **>(f2fs_fsck_argv),
JP Abgrall12351582014-06-17 17:01:14 -0700185 &status, true, LOG_KLOG | LOG_FILE,
bowgotsaicea7ea72017-01-16 21:49:49 +0800186 true, const_cast<char *>(FSCK_LOG_FILE),
187 NULL, 0);
JP Abgrall12351582014-06-17 17:01:14 -0700188 if (ret < 0) {
189 /* No need to check for error in fork, we can't really handle it now */
bowgotsai47878de2017-01-23 14:04:34 +0800190 LERROR << "Failed trying to run " << F2FS_FSCK_BIN;
JP Abgrall12351582014-06-17 17:01:14 -0700191 }
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800192 }
193
194 return;
195}
196
liminghao9a0fd1d2016-07-22 11:48:14 +0800197/* Function to read the primary superblock */
198static int read_super_block(int fd, struct ext4_super_block *sb)
199{
200 off64_t ret;
201
202 ret = lseek64(fd, 1024, SEEK_SET);
203 if (ret < 0)
204 return ret;
205
206 ret = read(fd, sb, sizeof(*sb));
207 if (ret < 0)
208 return ret;
209 if (ret != sizeof(*sb))
210 return ret;
211
212 return 0;
213}
214
215static ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
216{
217 return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
218 le32_to_cpu(es->s_blocks_count_lo);
219}
220
221static ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es)
222{
223 return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
224 le32_to_cpu(es->s_r_blocks_count_lo);
225}
226
Jeff Sharkey6d896102016-12-14 12:00:51 -0700227static int do_quota(char *blk_device, char *fs_type, struct fstab_rec *rec)
228{
229 int force_check = 0;
230 if (!strcmp(fs_type, "ext4")) {
231 /*
232 * Some system images do not have tune2fs for licensing reasons
233 * Detect these and skip reserve blocks.
234 */
235 if (access(TUNE2FS_BIN, X_OK)) {
bowgotsai47878de2017-01-23 14:04:34 +0800236 LERROR << "Not running " << TUNE2FS_BIN << " on "
237 << blk_device << " (executable not in system image)";
Jeff Sharkey6d896102016-12-14 12:00:51 -0700238 } else {
bowgotsaicea7ea72017-01-16 21:49:49 +0800239 const char* arg1 = nullptr;
240 const char* arg2 = nullptr;
Jeff Sharkey6d896102016-12-14 12:00:51 -0700241 int status = 0;
242 int ret = 0;
bowgotsaicea7ea72017-01-16 21:49:49 +0800243 android::base::unique_fd fd(
244 TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)));
Jeff Sharkey6d896102016-12-14 12:00:51 -0700245 if (fd >= 0) {
246 struct ext4_super_block sb;
247 ret = read_super_block(fd, &sb);
248 if (ret < 0) {
bowgotsai47878de2017-01-23 14:04:34 +0800249 PERROR << "Can't read '" << blk_device << "' super block";
bowgotsaicea7ea72017-01-16 21:49:49 +0800250 return force_check;
Jeff Sharkey6d896102016-12-14 12:00:51 -0700251 }
252
253 int has_quota = (sb.s_feature_ro_compat
254 & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0;
255 int want_quota = fs_mgr_is_quota(rec) != 0;
256
257 if (has_quota == want_quota) {
bowgotsai47878de2017-01-23 14:04:34 +0800258 LINFO << "Requested quota status is match on " << blk_device;
bowgotsaicea7ea72017-01-16 21:49:49 +0800259 return force_check;
Jeff Sharkey6d896102016-12-14 12:00:51 -0700260 } else if (want_quota) {
bowgotsai47878de2017-01-23 14:04:34 +0800261 LINFO << "Enabling quota on " << blk_device;
Jeff Sharkey6d896102016-12-14 12:00:51 -0700262 arg1 = "-Oquota";
263 arg2 = "-Qusrquota,grpquota";
264 force_check = 1;
265 } else {
bowgotsai47878de2017-01-23 14:04:34 +0800266 LINFO << "Disabling quota on " << blk_device;
Jeff Sharkey6d896102016-12-14 12:00:51 -0700267 arg1 = "-Q^usrquota,^grpquota";
268 arg2 = "-O^quota";
269 }
270 } else {
bowgotsai47878de2017-01-23 14:04:34 +0800271 PERROR << "Failed to open '" << blk_device << "'";
Jeff Sharkey6d896102016-12-14 12:00:51 -0700272 return force_check;
273 }
274
bowgotsaicea7ea72017-01-16 21:49:49 +0800275 const char *tune2fs_argv[] = {
Jeff Sharkey6d896102016-12-14 12:00:51 -0700276 TUNE2FS_BIN,
277 arg1,
278 arg2,
279 blk_device,
280 };
bowgotsaicea7ea72017-01-16 21:49:49 +0800281 ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv),
282 const_cast<char **>(tune2fs_argv),
Jeff Sharkey6d896102016-12-14 12:00:51 -0700283 &status, true, LOG_KLOG | LOG_FILE,
284 true, NULL, NULL, 0);
285 if (ret < 0) {
286 /* No need to check for error in fork, we can't really handle it now */
bowgotsai47878de2017-01-23 14:04:34 +0800287 LERROR << "Failed trying to run " << TUNE2FS_BIN;
Jeff Sharkey6d896102016-12-14 12:00:51 -0700288 }
Jeff Sharkey6d896102016-12-14 12:00:51 -0700289 }
290 }
291 return force_check;
292}
293
liminghao9a0fd1d2016-07-22 11:48:14 +0800294static void do_reserved_size(char *blk_device, char *fs_type, struct fstab_rec *rec)
295{
296 /* Check for the types of filesystems we know how to check */
297 if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
298 /*
299 * Some system images do not have tune2fs for licensing reasons
300 * Detect these and skip reserve blocks.
301 */
302 if (access(TUNE2FS_BIN, X_OK)) {
bowgotsai47878de2017-01-23 14:04:34 +0800303 LERROR << "Not running " << TUNE2FS_BIN << " on "
304 << blk_device << " (executable not in system image)";
liminghao9a0fd1d2016-07-22 11:48:14 +0800305 } else {
bowgotsai47878de2017-01-23 14:04:34 +0800306 LINFO << "Running " << TUNE2FS_BIN << " on " << blk_device;
liminghao9a0fd1d2016-07-22 11:48:14 +0800307
308 int status = 0;
309 int ret = 0;
310 unsigned long reserved_blocks = 0;
bowgotsaicea7ea72017-01-16 21:49:49 +0800311 android::base::unique_fd fd(
312 TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)));
liminghao9a0fd1d2016-07-22 11:48:14 +0800313 if (fd >= 0) {
314 struct ext4_super_block sb;
315 ret = read_super_block(fd, &sb);
316 if (ret < 0) {
bowgotsai47878de2017-01-23 14:04:34 +0800317 PERROR << "Can't read '" << blk_device << "' super block";
bowgotsaicea7ea72017-01-16 21:49:49 +0800318 return;
liminghao9a0fd1d2016-07-22 11:48:14 +0800319 }
320 reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(&sb);
321 unsigned long reserved_threshold = ext4_blocks_count(&sb) * 0.02;
322 if (reserved_threshold < reserved_blocks) {
bowgotsai47878de2017-01-23 14:04:34 +0800323 LWARNING << "Reserved blocks " << reserved_blocks
324 << " is too large";
liminghao9a0fd1d2016-07-22 11:48:14 +0800325 reserved_blocks = reserved_threshold;
326 }
327
328 if (ext4_r_blocks_count(&sb) == reserved_blocks) {
bowgotsai47878de2017-01-23 14:04:34 +0800329 LINFO << "Have reserved same blocks";
bowgotsaicea7ea72017-01-16 21:49:49 +0800330 return;
liminghao9a0fd1d2016-07-22 11:48:14 +0800331 }
332 } else {
bowgotsai47878de2017-01-23 14:04:34 +0800333 PERROR << "Failed to open '" << blk_device << "'";
liminghao9a0fd1d2016-07-22 11:48:14 +0800334 return;
335 }
336
337 char buf[16] = {0};
338 snprintf(buf, sizeof (buf), "-r %lu", reserved_blocks);
bowgotsaicea7ea72017-01-16 21:49:49 +0800339 const char *tune2fs_argv[] = {
liminghao9a0fd1d2016-07-22 11:48:14 +0800340 TUNE2FS_BIN,
341 buf,
342 blk_device,
343 };
344
bowgotsaicea7ea72017-01-16 21:49:49 +0800345 ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv),
346 const_cast<char **>(tune2fs_argv),
liminghao9a0fd1d2016-07-22 11:48:14 +0800347 &status, true, LOG_KLOG | LOG_FILE,
348 true, NULL, NULL, 0);
349
350 if (ret < 0) {
351 /* No need to check for error in fork, we can't really handle it now */
bowgotsai47878de2017-01-23 14:04:34 +0800352 LERROR << "Failed trying to run " << TUNE2FS_BIN;
liminghao9a0fd1d2016-07-22 11:48:14 +0800353 }
liminghao9a0fd1d2016-07-22 11:48:14 +0800354 }
355 }
356}
357
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800358static void remove_trailing_slashes(char *n)
359{
360 int len;
361
362 len = strlen(n) - 1;
363 while ((*(n + len) == '/') && len) {
364 *(n + len) = '\0';
365 len--;
366 }
367}
368
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700369/*
370 * Mark the given block device as read-only, using the BLKROSET ioctl.
371 * Return 0 on success, and -1 on error.
372 */
Sami Tolvanen214f33b2014-12-18 16:15:30 +0000373int fs_mgr_set_blk_ro(const char *blockdev)
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700374{
375 int fd;
Sami Tolvanen214f33b2014-12-18 16:15:30 +0000376 int rc = -1;
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700377 int ON = 1;
378
Sami Tolvanen214f33b2014-12-18 16:15:30 +0000379 fd = TEMP_FAILURE_RETRY(open(blockdev, O_RDONLY | O_CLOEXEC));
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700380 if (fd < 0) {
381 // should never happen
Sami Tolvanen214f33b2014-12-18 16:15:30 +0000382 return rc;
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700383 }
384
Sami Tolvanen214f33b2014-12-18 16:15:30 +0000385 rc = ioctl(fd, BLKROSET, &ON);
Elliott Hughes9fc83432015-05-15 19:16:40 -0700386 close(fd);
Sami Tolvanen214f33b2014-12-18 16:15:30 +0000387
388 return rc;
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700389}
390
391/*
392 * __mount(): wrapper around the mount() system call which also
393 * sets the underlying block device to read-only if the mount is read-only.
394 * See "man 2 mount" for return values.
395 */
JP Abgrall5c01dac2014-06-18 14:54:37 -0700396static int __mount(const char *source, const char *target, const struct fstab_rec *rec)
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700397{
JP Abgrall5c01dac2014-06-18 14:54:37 -0700398 unsigned long mountflags = rec->flags;
399 int ret;
400 int save_errno;
Daniel Rosenbergf67d6bd2014-06-26 14:55:04 -0700401
402 /* We need this because sometimes we have legacy symlinks
403 * that are lingering around and need cleaning up.
404 */
405 struct stat info;
406 if (!lstat(target, &info))
407 if ((info.st_mode & S_IFMT) == S_IFLNK)
408 unlink(target);
Daniel Rosenbergf530c932014-05-28 14:10:01 -0700409 mkdir(target, 0755);
JP Abgrall5c01dac2014-06-18 14:54:37 -0700410 ret = mount(source, target, rec->fs_type, mountflags, rec->fs_options);
411 save_errno = errno;
bowgotsai47878de2017-01-23 14:04:34 +0800412 LINFO << __FUNCTION__ << "(source=" << source << ",target="
413 << target << ",type=" << rec->fs_type << ")=" << ret;
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700414 if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
Sami Tolvanen214f33b2014-12-18 16:15:30 +0000415 fs_mgr_set_blk_ro(source);
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700416 }
JP Abgrall5c01dac2014-06-18 14:54:37 -0700417 errno = save_errno;
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700418 return ret;
419}
420
Jin Qian8b7eb7b2016-11-03 13:36:35 -0700421static int fs_match(const char *in1, const char *in2)
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800422{
423 char *n1;
424 char *n2;
425 int ret;
426
427 n1 = strdup(in1);
428 n2 = strdup(in2);
429
430 remove_trailing_slashes(n1);
431 remove_trailing_slashes(n2);
432
433 ret = !strcmp(n1, n2);
434
435 free(n1);
436 free(n2);
437
438 return ret;
439}
440
Paul Lawrencebbb36312014-10-09 14:22:49 +0000441static int device_is_secure() {
442 int ret = -1;
443 char value[PROP_VALUE_MAX];
444 ret = __system_property_get("ro.secure", value);
445 /* If error, we want to fail secure */
446 if (ret < 0)
447 return 1;
448 return strcmp(value, "0") ? 1 : 0;
449}
450
Paul Lawrence703b87d2015-01-07 11:44:51 -0800451static int device_is_force_encrypted() {
452 int ret = -1;
453 char value[PROP_VALUE_MAX];
454 ret = __system_property_get("ro.vold.forceencryption", value);
455 if (ret < 0)
456 return 0;
457 return strcmp(value, "1") ? 0 : 1;
458}
459
JP Abgrallf22b7452014-07-02 13:16:04 -0700460/*
461 * Tries to mount any of the consecutive fstab entries that match
462 * the mountpoint of the one given by fstab->recs[start_idx].
463 *
464 * end_idx: On return, will be the last rec that was looked at.
465 * attempted_idx: On return, will indicate which fstab rec
466 * succeeded. In case of failure, it will be the start_idx.
467 * Returns
468 * -1 on failure with errno set to match the 1st mount failure.
469 * 0 on success.
470 */
471static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_idx, int *attempted_idx)
JP Abgrall4bb7bba2014-06-19 22:12:20 -0700472{
JP Abgrallf22b7452014-07-02 13:16:04 -0700473 int i;
474 int mount_errno = 0;
475 int mounted = 0;
476
477 if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) {
478 errno = EINVAL;
479 if (end_idx) *end_idx = start_idx;
forfunc5c03062016-12-14 09:47:33 -0500480 if (attempted_idx) *attempted_idx = start_idx;
JP Abgrallf22b7452014-07-02 13:16:04 -0700481 return -1;
JP Abgrall4bb7bba2014-06-19 22:12:20 -0700482 }
JP Abgrallf22b7452014-07-02 13:16:04 -0700483
484 /* Hunt down an fstab entry for the same mount point that might succeed */
485 for (i = start_idx;
486 /* We required that fstab entries for the same mountpoint be consecutive */
487 i < fstab->num_entries && !strcmp(fstab->recs[start_idx].mount_point, fstab->recs[i].mount_point);
488 i++) {
489 /*
490 * Don't try to mount/encrypt the same mount point again.
491 * Deal with alternate entries for the same point which are required to be all following
492 * each other.
493 */
494 if (mounted) {
bowgotsai47878de2017-01-23 14:04:34 +0800495 LERROR << __FUNCTION__ << "(): skipping fstab dup mountpoint="
496 << fstab->recs[i].mount_point << " rec[" << i
497 << "].fs_type=" << fstab->recs[i].fs_type
498 << " already mounted as "
499 << fstab->recs[*attempted_idx].fs_type;
JP Abgrallf22b7452014-07-02 13:16:04 -0700500 continue;
501 }
502
Jeff Sharkey6d896102016-12-14 12:00:51 -0700503 int force_check = do_quota(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
504 &fstab->recs[i]);
505
506 if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) {
JP Abgrallf22b7452014-07-02 13:16:04 -0700507 check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
508 fstab->recs[i].mount_point);
509 }
liminghao9a0fd1d2016-07-22 11:48:14 +0800510
511 if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
512 do_reserved_size(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
513 &fstab->recs[i]);
514 }
515
JP Abgrallf22b7452014-07-02 13:16:04 -0700516 if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, &fstab->recs[i])) {
517 *attempted_idx = i;
518 mounted = 1;
519 if (i != start_idx) {
bowgotsai47878de2017-01-23 14:04:34 +0800520 LERROR << __FUNCTION__ << "(): Mounted "
521 << fstab->recs[i].blk_device << " on "
522 << fstab->recs[i].mount_point << " with fs_type="
523 << fstab->recs[i].fs_type << " instead of "
524 << fstab->recs[start_idx].fs_type;
JP Abgrallf22b7452014-07-02 13:16:04 -0700525 }
526 } else {
527 /* back up errno for crypto decisions */
528 mount_errno = errno;
529 }
530 }
531
532 /* Adjust i for the case where it was still withing the recs[] */
533 if (i < fstab->num_entries) --i;
534
535 *end_idx = i;
536 if (!mounted) {
537 *attempted_idx = start_idx;
538 errno = mount_errno;
539 return -1;
540 }
541 return 0;
JP Abgrall4bb7bba2014-06-19 22:12:20 -0700542}
543
Christoffer Dall82982342014-12-17 21:26:54 +0100544static int translate_ext_labels(struct fstab_rec *rec)
545{
546 DIR *blockdir = NULL;
547 struct dirent *ent;
548 char *label;
549 size_t label_len;
550 int ret = -1;
551
552 if (strncmp(rec->blk_device, "LABEL=", 6))
553 return 0;
554
555 label = rec->blk_device + 6;
556 label_len = strlen(label);
557
558 if (label_len > 16) {
bowgotsai47878de2017-01-23 14:04:34 +0800559 LERROR << "FS label is longer than allowed by filesystem";
Christoffer Dall82982342014-12-17 21:26:54 +0100560 goto out;
561 }
562
563
564 blockdir = opendir("/dev/block");
565 if (!blockdir) {
bowgotsai47878de2017-01-23 14:04:34 +0800566 LERROR << "couldn't open /dev/block";
Christoffer Dall82982342014-12-17 21:26:54 +0100567 goto out;
568 }
569
570 while ((ent = readdir(blockdir))) {
571 int fd;
572 char super_buf[1024];
573 struct ext4_super_block *sb;
574
575 if (ent->d_type != DT_BLK)
576 continue;
577
578 fd = openat(dirfd(blockdir), ent->d_name, O_RDONLY);
579 if (fd < 0) {
bowgotsai47878de2017-01-23 14:04:34 +0800580 LERROR << "Cannot open block device /dev/block/" << ent->d_name;
Christoffer Dall82982342014-12-17 21:26:54 +0100581 goto out;
582 }
583
584 if (TEMP_FAILURE_RETRY(lseek(fd, 1024, SEEK_SET)) < 0 ||
585 TEMP_FAILURE_RETRY(read(fd, super_buf, 1024)) != 1024) {
586 /* Probably a loopback device or something else without a readable
587 * superblock.
588 */
589 close(fd);
590 continue;
591 }
592
593 sb = (struct ext4_super_block *)super_buf;
594 if (sb->s_magic != EXT4_SUPER_MAGIC) {
bowgotsai47878de2017-01-23 14:04:34 +0800595 LINFO << "/dev/block/" << ent->d_name << " not ext{234}";
Christoffer Dall82982342014-12-17 21:26:54 +0100596 continue;
597 }
598
599 if (!strncmp(label, sb->s_volume_name, label_len)) {
600 char *new_blk_device;
601
602 if (asprintf(&new_blk_device, "/dev/block/%s", ent->d_name) < 0) {
bowgotsai47878de2017-01-23 14:04:34 +0800603 LERROR << "Could not allocate block device string";
Christoffer Dall82982342014-12-17 21:26:54 +0100604 goto out;
605 }
606
bowgotsai47878de2017-01-23 14:04:34 +0800607 LINFO << "resolved label " << rec->blk_device << " to "
608 << new_blk_device;
Christoffer Dall82982342014-12-17 21:26:54 +0100609
610 free(rec->blk_device);
611 rec->blk_device = new_blk_device;
612 ret = 0;
613 break;
614 }
615 }
616
617out:
618 closedir(blockdir);
619 return ret;
620}
621
Paul Crowleyc31f1f32016-02-09 21:05:01 +0000622static bool needs_block_encryption(const struct fstab_rec* rec)
623{
624 if (device_is_force_encrypted() && fs_mgr_is_encryptable(rec)) return true;
625 if (rec->fs_mgr_flags & MF_FORCECRYPT) return true;
626 if (rec->fs_mgr_flags & MF_CRYPT) {
627 /* Check for existence of convert_fde breadcrumb file */
628 char convert_fde_name[PATH_MAX];
629 snprintf(convert_fde_name, sizeof(convert_fde_name),
630 "%s/misc/vold/convert_fde", rec->mount_point);
631 if (access(convert_fde_name, F_OK) == 0) return true;
632 }
633 if (rec->fs_mgr_flags & MF_FORCEFDEORFBE) {
634 /* Check for absence of convert_fbe breadcrumb file */
635 char convert_fbe_name[PATH_MAX];
636 snprintf(convert_fbe_name, sizeof(convert_fbe_name),
637 "%s/convert_fbe", rec->mount_point);
638 if (access(convert_fbe_name, F_OK) != 0) return true;
639 }
640 return false;
641}
642
Paul Lawrenceb8c9d272015-03-26 15:49:42 +0000643// Check to see if a mountable volume has encryption requirements
Paul Lawrence69080182016-02-02 10:31:30 -0800644static int handle_encryptable(const struct fstab_rec* rec)
Paul Lawrenceb8c9d272015-03-26 15:49:42 +0000645{
646 /* If this is block encryptable, need to trigger encryption */
Paul Crowleyc31f1f32016-02-09 21:05:01 +0000647 if (needs_block_encryption(rec)) {
Paul Lawrenceb8c9d272015-03-26 15:49:42 +0000648 if (umount(rec->mount_point) == 0) {
649 return FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION;
650 } else {
bowgotsai47878de2017-01-23 14:04:34 +0800651 PWARNING << "Could not umount " << rec->mount_point
652 << " - allow continue unencrypted";
Paul Lawrenceb8c9d272015-03-26 15:49:42 +0000653 return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
654 }
Paul Crowleyc31f1f32016-02-09 21:05:01 +0000655 } else if (rec->fs_mgr_flags & (MF_FILEENCRYPTION | MF_FORCEFDEORFBE)) {
bowgotsai47878de2017-01-23 14:04:34 +0800656 // Deal with file level encryption
657 LINFO << rec->mount_point << " is file encrypted";
Paul Lawrence69080182016-02-02 10:31:30 -0800658 return FS_MGR_MNTALL_DEV_FILE_ENCRYPTED;
Paul Lawrence1098aac2016-03-04 15:52:33 -0800659 } else if (fs_mgr_is_encryptable(rec)) {
Paul Crowleyc31f1f32016-02-09 21:05:01 +0000660 return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
Paul Lawrence1098aac2016-03-04 15:52:33 -0800661 } else {
662 return FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
Paul Lawrenceb8c9d272015-03-26 15:49:42 +0000663 }
Paul Lawrenceb8c9d272015-03-26 15:49:42 +0000664}
665
bowgotsai3de625d2016-11-11 21:05:44 +0800666int fs_mgr_test_access(const char *device) {
667 int tries = 25;
668 while (tries--) {
669 if (!access(device, F_OK) || errno != ENOENT) {
670 return 0;
671 }
672 usleep(40 * 1000);
673 }
674 return -1;
675}
676
JP Abgrall5c01dac2014-06-18 14:54:37 -0700677/* When multiple fstab records share the same mount_point, it will
678 * try to mount each one in turn, and ignore any duplicates after a
679 * first successful mount.
JP Abgrallf22b7452014-07-02 13:16:04 -0700680 * Returns -1 on error, and FS_MGR_MNTALL_* otherwise.
JP Abgrall5c01dac2014-06-18 14:54:37 -0700681 */
Wei Wang254f4432016-08-23 11:58:09 -0700682int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800683{
JP Abgrallf22b7452014-07-02 13:16:04 -0700684 int i = 0;
Paul Lawrence1098aac2016-03-04 15:52:33 -0800685 int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700686 int error_count = 0;
JP Abgrall5c01dac2014-06-18 14:54:37 -0700687 int mret = -1;
688 int mount_errno = 0;
JP Abgrallf22b7452014-07-02 13:16:04 -0700689 int attempted_idx = -1;
bowgotsaib51722b2017-01-11 22:21:38 +0800690 int avb_ret = FS_MGR_SETUP_AVB_FAIL;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800691
Ken Sumrallab6b8522013-02-13 12:58:40 -0800692 if (!fstab) {
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700693 return -1;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800694 }
695
bowgotsaib51722b2017-01-11 22:21:38 +0800696 if (fs_mgr_is_avb_used() &&
697 (avb_ret = fs_mgr_load_vbmeta_images(fstab)) == FS_MGR_SETUP_AVB_FAIL) {
698 return -1;
699 }
700
Ken Sumrallab6b8522013-02-13 12:58:40 -0800701 for (i = 0; i < fstab->num_entries; i++) {
Wei Wang254f4432016-08-23 11:58:09 -0700702 /* Don't mount entries that are managed by vold or not for the mount mode*/
703 if ((fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) ||
704 ((mount_mode == MOUNT_MODE_LATE) && !fs_mgr_is_latemount(&fstab->recs[i])) ||
705 ((mount_mode == MOUNT_MODE_EARLY) && fs_mgr_is_latemount(&fstab->recs[i]))) {
Ken Sumrallab6b8522013-02-13 12:58:40 -0800706 continue;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800707 }
708
Ken Sumrall5bc31a22013-07-08 19:11:55 -0700709 /* Skip swap and raw partition entries such as boot, recovery, etc */
710 if (!strcmp(fstab->recs[i].fs_type, "swap") ||
711 !strcmp(fstab->recs[i].fs_type, "emmc") ||
Ken Sumrallab6b8522013-02-13 12:58:40 -0800712 !strcmp(fstab->recs[i].fs_type, "mtd")) {
713 continue;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800714 }
715
Daniel Rosenberg31a4faf2015-06-29 17:33:05 -0700716 /* Skip mounting the root partition, as it will already have been mounted */
717 if (!strcmp(fstab->recs[i].mount_point, "/")) {
718 if ((fstab->recs[i].fs_mgr_flags & MS_RDONLY) != 0) {
719 fs_mgr_set_blk_ro(fstab->recs[i].blk_device);
720 }
721 continue;
722 }
723
Christoffer Dall82982342014-12-17 21:26:54 +0100724 /* Translate LABEL= file system labels into block devices */
725 if (!strcmp(fstab->recs[i].fs_type, "ext2") ||
726 !strcmp(fstab->recs[i].fs_type, "ext3") ||
727 !strcmp(fstab->recs[i].fs_type, "ext4")) {
728 int tret = translate_ext_labels(&fstab->recs[i]);
729 if (tret < 0) {
bowgotsai47878de2017-01-23 14:04:34 +0800730 LERROR << "Could not translate label to block device";
Christoffer Dall82982342014-12-17 21:26:54 +0100731 continue;
732 }
733 }
734
Ken Sumrallab6b8522013-02-13 12:58:40 -0800735 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
736 wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
737 }
738
bowgotsaib51722b2017-01-11 22:21:38 +0800739 if (fs_mgr_is_avb_used() && (fstab->recs[i].fs_mgr_flags & MF_AVB)) {
740 /* If HASHTREE_DISABLED is set (cf. 'adb disable-verity'), we
741 * should set up the device without using dm-verity.
742 * The actual mounting still take place in the following
743 * mount_with_alternatives().
744 */
745 if (avb_ret == FS_MGR_SETUP_AVB_HASHTREE_DISABLED) {
bowgotsai47878de2017-01-23 14:04:34 +0800746 LINFO << "AVB HASHTREE disabled";
bowgotsaib51722b2017-01-11 22:21:38 +0800747 } else if (fs_mgr_setup_avb(&fstab->recs[i]) !=
748 FS_MGR_SETUP_AVB_SUCCESS) {
bowgotsai47878de2017-01-23 14:04:34 +0800749 LERROR << "Failed to set up AVB on partition: "
750 << fstab->recs[i].mount_point << ", skipping!";
bowgotsaib51722b2017-01-11 22:21:38 +0800751 /* Skips mounting the device. */
752 continue;
753 }
754 } else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
Hung-ying Tyanecfce132016-12-16 15:00:05 +0800755 int rc = fs_mgr_setup_verity(&fstab->recs[i], true);
Mark Salyzyne528be52016-03-29 14:25:11 -0700756 if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
bowgotsai47878de2017-01-23 14:04:34 +0800757 LINFO << "Verity disabled";
Paul Lawrencebbb36312014-10-09 14:22:49 +0000758 } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
bowgotsai47878de2017-01-23 14:04:34 +0800759 LERROR << "Could not set up verified partition, skipping!";
Geremy Condra3ad3d1c2013-02-22 18:11:41 -0800760 continue;
761 }
762 }
bowgotsaib51722b2017-01-11 22:21:38 +0800763
JP Abgrallf22b7452014-07-02 13:16:04 -0700764 int last_idx_inspected;
Chris Fries79f33842013-09-05 13:19:21 -0500765 int top_idx = i;
766
JP Abgrallf22b7452014-07-02 13:16:04 -0700767 mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
768 i = last_idx_inspected;
769 mount_errno = errno;
JP Abgrallf786fe52014-06-18 07:28:14 +0000770
JP Abgrall5c01dac2014-06-18 14:54:37 -0700771 /* Deal with encryptability. */
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800772 if (!mret) {
Paul Lawrence69080182016-02-02 10:31:30 -0800773 int status = handle_encryptable(&fstab->recs[attempted_idx]);
Paul Lawrenceb8c9d272015-03-26 15:49:42 +0000774
775 if (status == FS_MGR_MNTALL_FAIL) {
776 /* Fatal error - no point continuing */
777 return status;
Paul Lawrence166fa3d2014-02-03 13:27:49 -0800778 }
Paul Lawrenceb8c9d272015-03-26 15:49:42 +0000779
Paul Lawrence1098aac2016-03-04 15:52:33 -0800780 if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
781 if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
Paul Lawrenceb8c9d272015-03-26 15:49:42 +0000782 // Log and continue
bowgotsai47878de2017-01-23 14:04:34 +0800783 LERROR << "Only one encryptable/encrypted partition supported";
Paul Lawrenceb8c9d272015-03-26 15:49:42 +0000784 }
785 encryptable = status;
786 }
787
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800788 /* Success! Go get the next one */
789 continue;
790 }
791
Chris Fries79f33842013-09-05 13:19:21 -0500792 /* mount(2) returned an error, handle the encryptable/formattable case */
793 bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
Chuanxiao Dongd78dff12016-03-08 15:54:55 +0100794 bool crypt_footer = false;
Chris Fries79f33842013-09-05 13:19:21 -0500795 if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
796 fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) {
797 /* top_idx and attempted_idx point at the same partition, but sometimes
798 * at two different lines in the fstab. Use the top one for formatting
799 * as that is the preferred one.
800 */
bowgotsai47878de2017-01-23 14:04:34 +0800801 LERROR << __FUNCTION__ << "(): " << fstab->recs[top_idx].blk_device
802 << " is wiped and " << fstab->recs[top_idx].mount_point
803 << " " << fstab->recs[top_idx].fs_type
804 << " is formattable. Format it.";
Chris Fries79f33842013-09-05 13:19:21 -0500805 if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
806 strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
George Burgess IVe7aa2b22016-03-02 14:02:55 -0800807 int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY);
Chris Fries79f33842013-09-05 13:19:21 -0500808 if (fd >= 0) {
bowgotsai47878de2017-01-23 14:04:34 +0800809 LINFO << __FUNCTION__ << "(): also wipe "
810 << fstab->recs[top_idx].key_loc;
Chris Fries79f33842013-09-05 13:19:21 -0500811 wipe_block_device(fd, get_file_size(fd));
812 close(fd);
813 } else {
bowgotsai47878de2017-01-23 14:04:34 +0800814 PERROR << __FUNCTION__ << "(): "
815 << fstab->recs[top_idx].key_loc << " wouldn't open";
Chris Fries79f33842013-09-05 13:19:21 -0500816 }
Chuanxiao Dongd78dff12016-03-08 15:54:55 +0100817 } else if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
818 !strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
819 crypt_footer = true;
Chris Fries79f33842013-09-05 13:19:21 -0500820 }
Chuanxiao Dongd78dff12016-03-08 15:54:55 +0100821 if (fs_mgr_do_format(&fstab->recs[top_idx], crypt_footer) == 0) {
Chris Fries79f33842013-09-05 13:19:21 -0500822 /* Let's replay the mount actions. */
823 i = top_idx - 1;
824 continue;
Matthew Bouyack9c59cbc2016-05-02 15:55:30 -0700825 } else {
bowgotsai47878de2017-01-23 14:04:34 +0800826 LERROR << __FUNCTION__ << "(): Format failed. "
827 << "Suggest recovery...";
Matthew Bouyack9c59cbc2016-05-02 15:55:30 -0700828 encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
829 continue;
Chris Fries79f33842013-09-05 13:19:21 -0500830 }
831 }
JP Abgrall5c01dac2014-06-18 14:54:37 -0700832 if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
JP Abgrallcee20682014-07-02 14:26:54 -0700833 fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
Chris Fries79f33842013-09-05 13:19:21 -0500834 if (wiped) {
bowgotsai47878de2017-01-23 14:04:34 +0800835 LERROR << __FUNCTION__ << "(): "
836 << fstab->recs[attempted_idx].blk_device
837 << " is wiped and "
838 << fstab->recs[attempted_idx].mount_point << " "
839 << fstab->recs[attempted_idx].fs_type
840 << " is encryptable. Suggest recovery...";
JP Abgrallcee20682014-07-02 14:26:54 -0700841 encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700842 continue;
JP Abgrall4bb7bba2014-06-19 22:12:20 -0700843 } else {
844 /* Need to mount a tmpfs at this mountpoint for now, and set
845 * properties that vold will query later for decrypting
846 */
bowgotsai47878de2017-01-23 14:04:34 +0800847 LERROR << __FUNCTION__ << "(): possibly an encryptable blkdev "
848 << fstab->recs[attempted_idx].blk_device
849 << " for mount " << fstab->recs[attempted_idx].mount_point
850 << " type " << fstab->recs[attempted_idx].fs_type;
JP Abgrallf22b7452014-07-02 13:16:04 -0700851 if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
JP Abgrall4bb7bba2014-06-19 22:12:20 -0700852 ++error_count;
853 continue;
854 }
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800855 }
JP Abgrallf22b7452014-07-02 13:16:04 -0700856 encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800857 } else {
Daniel Rosenbergd38e3c52016-04-07 20:10:25 -0700858 if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) {
bowgotsai47878de2017-01-23 14:04:34 +0800859 PERROR << "Ignoring failure to mount an un-encryptable or wiped partition on"
860 << fstab->recs[attempted_idx].blk_device << " at "
861 << fstab->recs[attempted_idx].mount_point << " options: "
862 << fstab->recs[attempted_idx].fs_options;
Daniel Rosenbergd38e3c52016-04-07 20:10:25 -0700863 } else {
bowgotsai47878de2017-01-23 14:04:34 +0800864 PERROR << "Failed to mount an un-encryptable or wiped partition on"
865 << fstab->recs[attempted_idx].blk_device << " at "
866 << fstab->recs[attempted_idx].mount_point << " options: "
867 << fstab->recs[attempted_idx].fs_options;
Daniel Rosenbergd38e3c52016-04-07 20:10:25 -0700868 ++error_count;
869 }
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700870 continue;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800871 }
872 }
873
bowgotsaib51722b2017-01-11 22:21:38 +0800874 if (fs_mgr_is_avb_used()) {
875 fs_mgr_unload_vbmeta_images();
876 }
877
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700878 if (error_count) {
879 return -1;
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700880 } else {
Paul Lawrence166fa3d2014-02-03 13:27:49 -0800881 return encryptable;
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700882 }
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800883}
884
Ken Sumrallab6b8522013-02-13 12:58:40 -0800885/* If tmp_mount_point is non-null, mount the filesystem there. This is for the
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800886 * tmp mount we do to check the user password
JP Abgrall5c01dac2014-06-18 14:54:37 -0700887 * If multiple fstab entries are to be mounted on "n_name", it will try to mount each one
888 * in turn, and stop on 1st success, or no more match.
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800889 */
Jin Qian8b7eb7b2016-11-03 13:36:35 -0700890int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
Ken Sumrallab6b8522013-02-13 12:58:40 -0800891 char *tmp_mount_point)
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800892{
893 int i = 0;
Paul Lawrencecf234dc2014-09-09 10:44:51 -0700894 int ret = FS_MGR_DOMNT_FAILED;
JP Abgrall5c01dac2014-06-18 14:54:37 -0700895 int mount_errors = 0;
896 int first_mount_errno = 0;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800897 char *m;
bowgotsaib51722b2017-01-11 22:21:38 +0800898 int avb_ret = FS_MGR_SETUP_AVB_FAIL;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800899
Ken Sumrallab6b8522013-02-13 12:58:40 -0800900 if (!fstab) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800901 return ret;
902 }
903
bowgotsaib51722b2017-01-11 22:21:38 +0800904 if (fs_mgr_is_avb_used() &&
905 (avb_ret = fs_mgr_load_vbmeta_images(fstab)) == FS_MGR_SETUP_AVB_FAIL) {
906 return ret;
907 }
908
Ken Sumrallab6b8522013-02-13 12:58:40 -0800909 for (i = 0; i < fstab->num_entries; i++) {
910 if (!fs_match(fstab->recs[i].mount_point, n_name)) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800911 continue;
912 }
913
914 /* We found our match */
Ken Sumrall5bc31a22013-07-08 19:11:55 -0700915 /* If this swap or a raw partition, report an error */
916 if (!strcmp(fstab->recs[i].fs_type, "swap") ||
917 !strcmp(fstab->recs[i].fs_type, "emmc") ||
Ken Sumrallab6b8522013-02-13 12:58:40 -0800918 !strcmp(fstab->recs[i].fs_type, "mtd")) {
bowgotsai47878de2017-01-23 14:04:34 +0800919 LERROR << "Cannot mount filesystem of type "
920 << fstab->recs[i].fs_type << " on " << n_blk_device;
Ken Sumrallab6b8522013-02-13 12:58:40 -0800921 goto out;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800922 }
923
Ken Sumrallab6b8522013-02-13 12:58:40 -0800924 /* First check the filesystem if requested */
925 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
926 wait_for_file(n_blk_device, WAIT_TIMEOUT);
927 }
928
Jeff Sharkey6d896102016-12-14 12:00:51 -0700929 int force_check = do_quota(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
930 &fstab->recs[i]);
931
932 if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) {
Ken Sumrallab6b8522013-02-13 12:58:40 -0800933 check_fs(n_blk_device, fstab->recs[i].fs_type,
934 fstab->recs[i].mount_point);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800935 }
936
liminghao9a0fd1d2016-07-22 11:48:14 +0800937 if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
938 do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i]);
939 }
940
bowgotsaib51722b2017-01-11 22:21:38 +0800941 if (fs_mgr_is_avb_used() && (fstab->recs[i].fs_mgr_flags & MF_AVB)) {
942 /* If HASHTREE_DISABLED is set (cf. 'adb disable-verity'), we
943 * should set up the device without using dm-verity.
944 * The actual mounting still take place in the following
945 * mount_with_alternatives().
946 */
947 if (avb_ret == FS_MGR_SETUP_AVB_HASHTREE_DISABLED) {
bowgotsai47878de2017-01-23 14:04:34 +0800948 LINFO << "AVB HASHTREE disabled";
bowgotsaib51722b2017-01-11 22:21:38 +0800949 } else if (fs_mgr_setup_avb(&fstab->recs[i]) !=
950 FS_MGR_SETUP_AVB_SUCCESS) {
bowgotsai47878de2017-01-23 14:04:34 +0800951 LERROR << "Failed to set up AVB on partition: "
952 << fstab->recs[i].mount_point << ", skipping!";
bowgotsaib51722b2017-01-11 22:21:38 +0800953 /* Skips mounting the device. */
954 continue;
955 }
956 } else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
Hung-ying Tyanecfce132016-12-16 15:00:05 +0800957 int rc = fs_mgr_setup_verity(&fstab->recs[i], true);
Mark Salyzyne528be52016-03-29 14:25:11 -0700958 if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
bowgotsai47878de2017-01-23 14:04:34 +0800959 LINFO << "Verity disabled";
Paul Lawrencebbb36312014-10-09 14:22:49 +0000960 } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
bowgotsai47878de2017-01-23 14:04:34 +0800961 LERROR << "Could not set up verified partition, skipping!";
Geremy Condra3ad3d1c2013-02-22 18:11:41 -0800962 continue;
963 }
964 }
965
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800966 /* Now mount it where requested */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800967 if (tmp_mount_point) {
968 m = tmp_mount_point;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800969 } else {
Ken Sumrallab6b8522013-02-13 12:58:40 -0800970 m = fstab->recs[i].mount_point;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800971 }
JP Abgrall5c01dac2014-06-18 14:54:37 -0700972 if (__mount(n_blk_device, m, &fstab->recs[i])) {
973 if (!first_mount_errno) first_mount_errno = errno;
974 mount_errors++;
975 continue;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800976 } else {
977 ret = 0;
978 goto out;
979 }
980 }
JP Abgrall5c01dac2014-06-18 14:54:37 -0700981 if (mount_errors) {
bowgotsai47878de2017-01-23 14:04:34 +0800982 PERROR << "Cannot mount filesystem on " << n_blk_device
983 << " at " << m;
Paul Lawrencecf234dc2014-09-09 10:44:51 -0700984 if (first_mount_errno == EBUSY) {
985 ret = FS_MGR_DOMNT_BUSY;
986 } else {
987 ret = FS_MGR_DOMNT_FAILED;
988 }
JP Abgrall5c01dac2014-06-18 14:54:37 -0700989 } else {
990 /* We didn't find a match, say so and return an error */
bowgotsai47878de2017-01-23 14:04:34 +0800991 LERROR << "Cannot find mount point " << fstab->recs[i].mount_point
992 << " in fstab";
JP Abgrall5c01dac2014-06-18 14:54:37 -0700993 }
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800994
995out:
bowgotsaib51722b2017-01-11 22:21:38 +0800996 if (fs_mgr_is_avb_used()) {
997 fs_mgr_unload_vbmeta_images();
998 }
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800999 return ret;
1000}
1001
1002/*
1003 * mount a tmpfs filesystem at the given point.
1004 * return 0 on success, non-zero on failure.
1005 */
1006int fs_mgr_do_tmpfs_mount(char *n_name)
1007{
1008 int ret;
1009
1010 ret = mount("tmpfs", n_name, "tmpfs",
1011 MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS);
1012 if (ret < 0) {
bowgotsai47878de2017-01-23 14:04:34 +08001013 LERROR << "Cannot mount tmpfs filesystem at " << n_name;
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001014 return -1;
1015 }
1016
1017 /* Success */
1018 return 0;
1019}
1020
Ken Sumrallab6b8522013-02-13 12:58:40 -08001021int fs_mgr_unmount_all(struct fstab *fstab)
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001022{
1023 int i = 0;
1024 int ret = 0;
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001025
Ken Sumrallab6b8522013-02-13 12:58:40 -08001026 if (!fstab) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001027 return -1;
1028 }
1029
Ken Sumrallab6b8522013-02-13 12:58:40 -08001030 while (fstab->recs[i].blk_device) {
1031 if (umount(fstab->recs[i].mount_point)) {
bowgotsai47878de2017-01-23 14:04:34 +08001032 LERROR << "Cannot unmount filesystem at "
1033 << fstab->recs[i].mount_point;
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001034 ret = -1;
1035 }
1036 i++;
1037 }
1038
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001039 return ret;
1040}
Ken Sumrall5bc31a22013-07-08 19:11:55 -07001041
1042/* This must be called after mount_all, because the mkswap command needs to be
1043 * available.
1044 */
1045int fs_mgr_swapon_all(struct fstab *fstab)
1046{
1047 int i = 0;
1048 int flags = 0;
1049 int err = 0;
1050 int ret = 0;
1051 int status;
bowgotsaicea7ea72017-01-16 21:49:49 +08001052 const char *mkswap_argv[2] = {
Ken Sumrall5bc31a22013-07-08 19:11:55 -07001053 MKSWAP_BIN,
bowgotsaicea7ea72017-01-16 21:49:49 +08001054 nullptr
Ken Sumrall5bc31a22013-07-08 19:11:55 -07001055 };
1056
1057 if (!fstab) {
1058 return -1;
1059 }
1060
1061 for (i = 0; i < fstab->num_entries; i++) {
1062 /* Skip non-swap entries */
1063 if (strcmp(fstab->recs[i].fs_type, "swap")) {
1064 continue;
1065 }
1066
1067 if (fstab->recs[i].zram_size > 0) {
1068 /* A zram_size was specified, so we need to configure the
1069 * device. There is no point in having multiple zram devices
1070 * on a system (all the memory comes from the same pool) so
1071 * we can assume the device number is 0.
1072 */
1073 FILE *zram_fp;
Peter Enderborg4d217f02016-08-26 15:09:35 +02001074 FILE *zram_mcs_fp;
1075
1076 if (fstab->recs[i].max_comp_streams >= 0) {
1077 zram_mcs_fp = fopen(ZRAM_CONF_MCS, "r+");
1078 if (zram_mcs_fp == NULL) {
bowgotsai47878de2017-01-23 14:04:34 +08001079 LERROR << "Unable to open zram conf comp device "
1080 << ZRAM_CONF_MCS;
Peter Enderborg4d217f02016-08-26 15:09:35 +02001081 ret = -1;
1082 continue;
1083 }
1084 fprintf(zram_mcs_fp, "%d\n", fstab->recs[i].max_comp_streams);
1085 fclose(zram_mcs_fp);
1086 }
Ken Sumrall5bc31a22013-07-08 19:11:55 -07001087
1088 zram_fp = fopen(ZRAM_CONF_DEV, "r+");
1089 if (zram_fp == NULL) {
bowgotsai47878de2017-01-23 14:04:34 +08001090 LERROR << "Unable to open zram conf device " << ZRAM_CONF_DEV;
Ken Sumrall5bc31a22013-07-08 19:11:55 -07001091 ret = -1;
1092 continue;
1093 }
1094 fprintf(zram_fp, "%d\n", fstab->recs[i].zram_size);
1095 fclose(zram_fp);
1096 }
1097
1098 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
1099 wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
1100 }
1101
1102 /* Initialize the swap area */
1103 mkswap_argv[1] = fstab->recs[i].blk_device;
bowgotsaicea7ea72017-01-16 21:49:49 +08001104 err = android_fork_execvp_ext(ARRAY_SIZE(mkswap_argv),
1105 const_cast<char **>(mkswap_argv),
Yusuke Satod81c3c62015-08-14 01:22:53 -07001106 &status, true, LOG_KLOG, false, NULL,
1107 NULL, 0);
Ken Sumrall5bc31a22013-07-08 19:11:55 -07001108 if (err) {
bowgotsai47878de2017-01-23 14:04:34 +08001109 LERROR << "mkswap failed for " << fstab->recs[i].blk_device;
Ken Sumrall5bc31a22013-07-08 19:11:55 -07001110 ret = -1;
1111 continue;
1112 }
1113
1114 /* If -1, then no priority was specified in fstab, so don't set
1115 * SWAP_FLAG_PREFER or encode the priority */
1116 if (fstab->recs[i].swap_prio >= 0) {
1117 flags = (fstab->recs[i].swap_prio << SWAP_FLAG_PRIO_SHIFT) &
1118 SWAP_FLAG_PRIO_MASK;
1119 flags |= SWAP_FLAG_PREFER;
1120 } else {
1121 flags = 0;
1122 }
1123 err = swapon(fstab->recs[i].blk_device, flags);
1124 if (err) {
bowgotsai47878de2017-01-23 14:04:34 +08001125 LERROR << "swapon failed for " << fstab->recs[i].blk_device;
Ken Sumrall5bc31a22013-07-08 19:11:55 -07001126 ret = -1;
1127 }
1128 }
1129
1130 return ret;
1131}
1132
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001133/*
1134 * key_loc must be at least PROPERTY_VALUE_MAX bytes long
1135 *
Ken Sumrallab6b8522013-02-13 12:58:40 -08001136 * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001137 */
Ken Sumrallab6b8522013-02-13 12:58:40 -08001138int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_device, int size)
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001139{
1140 int i = 0;
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001141
Ken Sumrallab6b8522013-02-13 12:58:40 -08001142 if (!fstab) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001143 return -1;
1144 }
1145 /* Initialize return values to null strings */
1146 if (key_loc) {
1147 *key_loc = '\0';
1148 }
Ken Sumrallab6b8522013-02-13 12:58:40 -08001149 if (real_blk_device) {
1150 *real_blk_device = '\0';
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001151 }
1152
1153 /* Look for the encryptable partition to find the data */
Ken Sumrallab6b8522013-02-13 12:58:40 -08001154 for (i = 0; i < fstab->num_entries; i++) {
1155 /* Don't deal with vold managed enryptable partitions here */
1156 if (fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) {
1157 continue;
1158 }
Paul Lawrenceb262d682015-10-29 10:31:02 -07001159 if (!(fstab->recs[i].fs_mgr_flags
1160 & (MF_CRYPT | MF_FORCECRYPT | MF_FORCEFDEORFBE))) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001161 continue;
1162 }
1163
1164 /* We found a match */
1165 if (key_loc) {
Ken Sumrallab6b8522013-02-13 12:58:40 -08001166 strlcpy(key_loc, fstab->recs[i].key_loc, size);
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001167 }
Ken Sumrallab6b8522013-02-13 12:58:40 -08001168 if (real_blk_device) {
1169 strlcpy(real_blk_device, fstab->recs[i].blk_device, size);
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001170 }
1171 break;
1172 }
1173
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001174 return 0;
1175}
Hung-ying Tyan99c4a8a2016-02-01 15:07:40 +08001176
1177int fs_mgr_early_setup_verity(struct fstab_rec *fstab_rec)
1178{
1179 if ((fstab_rec->fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
Hung-ying Tyanecfce132016-12-16 15:00:05 +08001180 int rc = fs_mgr_setup_verity(fstab_rec, false);
Mark Salyzyne528be52016-03-29 14:25:11 -07001181 if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
bowgotsai47878de2017-01-23 14:04:34 +08001182 LINFO << "Verity disabled";
Hung-ying Tyan99c4a8a2016-02-01 15:07:40 +08001183 return FS_MGR_EARLY_SETUP_VERITY_NO_VERITY;
1184 } else if (rc == FS_MGR_SETUP_VERITY_SUCCESS) {
1185 return FS_MGR_EARLY_SETUP_VERITY_SUCCESS;
1186 } else {
1187 return FS_MGR_EARLY_SETUP_VERITY_FAIL;
1188 }
1189 } else if (device_is_secure()) {
bowgotsai47878de2017-01-23 14:04:34 +08001190 LERROR << "Verity must be enabled for early mounted partitions on secured devices";
Hung-ying Tyan99c4a8a2016-02-01 15:07:40 +08001191 return FS_MGR_EARLY_SETUP_VERITY_FAIL;
1192 }
1193 return FS_MGR_EARLY_SETUP_VERITY_NO_VERITY;
1194}