summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'fs_mgr/fs_mgr.cpp')
-rw-r--r--fs_mgr/fs_mgr.cpp476
1 files changed, 237 insertions, 239 deletions
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index e0093834b..91ed49663 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -32,6 +32,7 @@
32#include <unistd.h> 32#include <unistd.h>
33 33
34#include <memory> 34#include <memory>
35#include <thread>
35 36
36#include <android-base/file.h> 37#include <android-base/file.h>
37#include <android-base/properties.h> 38#include <android-base/properties.h>
@@ -78,43 +79,33 @@ enum FsStatFlags {
78 FS_STAT_E2FSCK_F_ALWAYS = 0x0004, 79 FS_STAT_E2FSCK_F_ALWAYS = 0x0004,
79 FS_STAT_UNCLEAN_SHUTDOWN = 0x0008, 80 FS_STAT_UNCLEAN_SHUTDOWN = 0x0008,
80 FS_STAT_QUOTA_ENABLED = 0x0010, 81 FS_STAT_QUOTA_ENABLED = 0x0010,
81 FS_STAT_TUNE2FS_FAILED = 0x0020,
82 FS_STAT_RO_MOUNT_FAILED = 0x0040, 82 FS_STAT_RO_MOUNT_FAILED = 0x0040,
83 FS_STAT_RO_UNMOUNT_FAILED = 0x0080, 83 FS_STAT_RO_UNMOUNT_FAILED = 0x0080,
84 FS_STAT_FULL_MOUNT_FAILED = 0x0100, 84 FS_STAT_FULL_MOUNT_FAILED = 0x0100,
85 FS_STAT_E2FSCK_FAILED = 0x0200, 85 FS_STAT_E2FSCK_FAILED = 0x0200,
86 FS_STAT_E2FSCK_FS_FIXED = 0x0400, 86 FS_STAT_E2FSCK_FS_FIXED = 0x0400,
87 FS_STAT_EXT4_INVALID_MAGIC = 0x0800, 87 FS_STAT_EXT4_INVALID_MAGIC = 0x0800,
88 FS_STAT_TOGGLE_QUOTAS_FAILED = 0x10000,
89 FS_STAT_SET_RESERVED_BLOCKS_FAILED = 0x20000,
90 FS_STAT_ENABLE_ENCRYPTION_FAILED = 0x40000,
88}; 91};
89 92
90/* 93// TODO: switch to inotify()
91 * gettime() - returns the time in seconds of the system's monotonic clock or 94bool fs_mgr_wait_for_file(const std::string& filename,
92 * zero on error. 95 const std::chrono::milliseconds relative_timeout) {
93 */ 96 auto start_time = std::chrono::steady_clock::now();
94static 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 97
105 return ts.tv_sec; 98 while (true) {
106} 99 if (!access(filename.c_str(), F_OK) || errno != ENOENT) {
107 100 return true;
108static int wait_for_file(const char *filename, int timeout) 101 }
109{
110 struct stat info;
111 time_t timeout_time = gettime() + timeout;
112 int ret = -1;
113 102
114 while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0)) 103 std::this_thread::sleep_for(50ms);
115 usleep(10000);
116 104
117 return ret; 105 auto now = std::chrono::steady_clock::now();
106 auto time_elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time);
107 if (time_elapsed > relative_timeout) return false;
108 }
118} 109}
119 110
120static void log_fs_stat(const char* blk_device, int fs_stat) 111static void log_fs_stat(const char* blk_device, int fs_stat)
@@ -128,10 +119,16 @@ static void log_fs_stat(const char* blk_device, int fs_stat)
128 } 119 }
129} 120}
130 121
122static bool is_extfs(const std::string& fs_type) {
123 return fs_type == "ext4" || fs_type == "ext3" || fs_type == "ext2";
124}
125
131static bool should_force_check(int fs_stat) { 126static bool should_force_check(int fs_stat) {
132 return fs_stat & (FS_STAT_E2FSCK_F_ALWAYS | FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED | 127 return fs_stat &
133 FS_STAT_TUNE2FS_FAILED | FS_STAT_RO_MOUNT_FAILED | FS_STAT_RO_UNMOUNT_FAILED | 128 (FS_STAT_E2FSCK_F_ALWAYS | FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED |
134 FS_STAT_FULL_MOUNT_FAILED | FS_STAT_E2FSCK_FAILED); 129 FS_STAT_RO_MOUNT_FAILED | FS_STAT_RO_UNMOUNT_FAILED | FS_STAT_FULL_MOUNT_FAILED |
130 FS_STAT_E2FSCK_FAILED | FS_STAT_TOGGLE_QUOTAS_FAILED |
131 FS_STAT_SET_RESERVED_BLOCKS_FAILED | FS_STAT_ENABLE_ENCRYPTION_FAILED);
135} 132}
136 133
137static void check_fs(const char *blk_device, char *fs_type, char *target, int *fs_stat) 134static void check_fs(const char *blk_device, char *fs_type, char *target, int *fs_stat)
@@ -144,7 +141,7 @@ static void check_fs(const char *blk_device, char *fs_type, char *target, int *f
144 const char* e2fsck_forced_argv[] = {E2FSCK_BIN, "-f", "-y", blk_device}; 141 const char* e2fsck_forced_argv[] = {E2FSCK_BIN, "-f", "-y", blk_device};
145 142
146 /* Check for the types of filesystems we know how to check */ 143 /* 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")) { 144 if (is_extfs(fs_type)) {
148 if (*fs_stat & FS_STAT_EXT4_INVALID_MAGIC) { // will fail, so do not try 145 if (*fs_stat & FS_STAT_EXT4_INVALID_MAGIC) { // will fail, so do not try
149 return; 146 return;
150 } 147 }
@@ -242,186 +239,208 @@ static void check_fs(const char *blk_device, char *fs_type, char *target, int *f
242 return; 239 return;
243} 240}
244 241
245/* Function to read the primary superblock */ 242static ext4_fsblk_t ext4_blocks_count(const struct ext4_super_block* es) {
246static int read_super_block(int fd, struct ext4_super_block *sb) 243 return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
247{ 244 le32_to_cpu(es->s_blocks_count_lo);
248 off64_t ret; 245}
249 246
250 ret = lseek64(fd, 1024, SEEK_SET); 247static ext4_fsblk_t ext4_r_blocks_count(const struct ext4_super_block* es) {
251 if (ret < 0) 248 return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
252 return ret; 249 le32_to_cpu(es->s_r_blocks_count_lo);
250}
253 251
254 ret = read(fd, sb, sizeof(*sb)); 252// Read the primary superblock from an ext4 filesystem. On failure return
255 if (ret < 0) 253// false. If it's not an ext4 filesystem, also set FS_STAT_EXT4_INVALID_MAGIC.
256 return ret; 254static bool read_ext4_superblock(const char* blk_device, struct ext4_super_block* sb, int* fs_stat) {
257 if (ret != sizeof(*sb)) 255 android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)));
258 return ret;
259 256
260 return 0; 257 if (fd < 0) {
258 PERROR << "Failed to open '" << blk_device << "'";
259 return false;
260 }
261
262 if (pread(fd, sb, sizeof(*sb), 1024) != sizeof(*sb)) {
263 PERROR << "Can't read '" << blk_device << "' superblock";
264 return false;
265 }
266
267 if (sb->s_magic != EXT4_SUPER_MAGIC) {
268 LINFO << "Invalid ext4 magic:0x" << std::hex << sb->s_magic << " "
269 << "on '" << blk_device << "'";
270 // not a valid fs, tune2fs, fsck, and mount will all fail.
271 *fs_stat |= FS_STAT_EXT4_INVALID_MAGIC;
272 return false;
273 }
274 *fs_stat |= FS_STAT_IS_EXT4;
275 LINFO << "superblock s_max_mnt_count:" << sb->s_max_mnt_count << "," << blk_device;
276 if (sb->s_max_mnt_count == 0xffff) { // -1 (int16) in ext2, but uint16 in ext4
277 *fs_stat |= FS_STAT_NEW_IMAGE_VERSION;
278 }
279 return true;
261} 280}
262 281
263static ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) 282// Some system images do not have tune2fs for licensing reasons.
264{ 283// Detect these and skip running it.
265 return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) | 284static bool tune2fs_available(void) {
266 le32_to_cpu(es->s_blocks_count_lo); 285 return access(TUNE2FS_BIN, X_OK) == 0;
267} 286}
268 287
269static ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es) 288static bool run_tune2fs(const char* argv[], int argc) {
270{ 289 int ret;
271 return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) | 290
272 le32_to_cpu(es->s_r_blocks_count_lo); 291 ret = android_fork_execvp_ext(argc, const_cast<char**>(argv), nullptr, true,
292 LOG_KLOG | LOG_FILE, true, nullptr, nullptr, 0);
293 return ret == 0;
273} 294}
274 295
275static int do_quota_with_shutdown_check(char *blk_device, char *fs_type, 296// Enable/disable quota support on the filesystem if needed.
276 struct fstab_rec *rec, int *fs_stat) 297static void tune_quota(const char* blk_device, const struct fstab_rec* rec,
277{ 298 const struct ext4_super_block* sb, int* fs_stat) {
278 int force_check = 0; 299 bool has_quota = (sb->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0;
279 if (!strcmp(fs_type, "ext4")) { 300 bool want_quota = fs_mgr_is_quota(rec) != 0;
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 301
342 const char *tune2fs_argv[] = { 302 if (has_quota == want_quota) {
343 TUNE2FS_BIN, 303 return;
344 arg1, 304 }
345 arg2, 305
346 blk_device, 306 if (!tune2fs_available()) {
347 }; 307 LERROR << "Unable to " << (want_quota ? "enable" : "disable") << " quotas on " << blk_device
348 ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv), 308 << " because " TUNE2FS_BIN " is missing";
349 const_cast<char **>(tune2fs_argv), 309 return;
350 &status, true, LOG_KLOG | LOG_FILE, 310 }
351 true, NULL, NULL, 0); 311
352 if (ret < 0) { 312 const char* argv[] = {TUNE2FS_BIN, nullptr, nullptr, blk_device};
353 /* No need to check for error in fork, we can't really handle it now */ 313
354 LERROR << "Failed trying to run " << TUNE2FS_BIN; 314 if (want_quota) {
355 *fs_stat |= FS_STAT_TUNE2FS_FAILED; 315 LINFO << "Enabling quotas on " << blk_device;
356 } 316 argv[1] = "-Oquota";
357 } 317 argv[2] = "-Qusrquota,grpquota";
318 *fs_stat |= FS_STAT_QUOTA_ENABLED;
319 } else {
320 LINFO << "Disabling quotas on " << blk_device;
321 argv[1] = "-O^quota";
322 argv[2] = "-Q^usrquota,^grpquota";
323 }
324
325 if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
326 LERROR << "Failed to run " TUNE2FS_BIN " to " << (want_quota ? "enable" : "disable")
327 << " quotas on " << blk_device;
328 *fs_stat |= FS_STAT_TOGGLE_QUOTAS_FAILED;
358 } 329 }
359 return force_check;
360} 330}
361 331
362static void do_reserved_size(char *blk_device, char *fs_type, struct fstab_rec *rec, int *fs_stat) 332// Set the number of reserved filesystem blocks if needed.
363{ 333static void tune_reserved_size(const char* blk_device, const struct fstab_rec* rec,
364 /* Check for the types of filesystems we know how to check */ 334 const struct ext4_super_block* sb, int* fs_stat) {
365 if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) { 335 if (!(rec->fs_mgr_flags & MF_RESERVEDSIZE)) {
366 /* 336 return;
367 * Some system images do not have tune2fs for licensing reasons 337 }
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 338
396 if (ext4_r_blocks_count(&sb) == reserved_blocks) { 339 // The size to reserve is given in the fstab, but we won't reserve more
397 LINFO << "Have reserved same blocks"; 340 // than 2% of the filesystem.
398 return; 341 const uint64_t max_reserved_blocks = ext4_blocks_count(sb) * 0.02;
399 } 342 uint64_t reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(sb);
400 } else {
401 PERROR << "Failed to open '" << blk_device << "'";
402 return;
403 }
404 343
405 char buf[16] = {0}; 344 if (reserved_blocks > max_reserved_blocks) {
406 snprintf(buf, sizeof (buf), "-r %lu", reserved_blocks); 345 LWARNING << "Reserved blocks " << reserved_blocks << " is too large; "
407 const char *tune2fs_argv[] = { 346 << "capping to " << max_reserved_blocks;
408 TUNE2FS_BIN, 347 reserved_blocks = max_reserved_blocks;
409 buf, 348 }
410 blk_device,
411 };
412 349
413 ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv), 350 if (ext4_r_blocks_count(sb) == reserved_blocks) {
414 const_cast<char **>(tune2fs_argv), 351 return;
415 &status, true, LOG_KLOG | LOG_FILE, 352 }
416 true, NULL, NULL, 0);
417 353
418 if (ret < 0) { 354 if (!tune2fs_available()) {
419 /* No need to check for error in fork, we can't really handle it now */ 355 LERROR << "Unable to set the number of reserved blocks on " << blk_device
420 LERROR << "Failed trying to run " << TUNE2FS_BIN; 356 << " because " TUNE2FS_BIN " is missing";
421 *fs_stat |= FS_STAT_TUNE2FS_FAILED; 357 return;
358 }
359
360 char buf[32];
361 const char* argv[] = {TUNE2FS_BIN, "-r", buf, blk_device};
362
363 snprintf(buf, sizeof(buf), "%" PRIu64, reserved_blocks);
364 LINFO << "Setting reserved block count on " << blk_device << " to " << reserved_blocks;
365 if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
366 LERROR << "Failed to run " TUNE2FS_BIN " to set the number of reserved blocks on "
367 << blk_device;
368 *fs_stat |= FS_STAT_SET_RESERVED_BLOCKS_FAILED;
369 }
370}
371
372// Enable file-based encryption if needed.
373static void tune_encrypt(const char* blk_device, const struct fstab_rec* rec,
374 const struct ext4_super_block* sb, int* fs_stat) {
375 bool has_encrypt = (sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_ENCRYPT)) != 0;
376 bool want_encrypt = fs_mgr_is_file_encrypted(rec) != 0;
377
378 if (has_encrypt || !want_encrypt) {
379 return;
380 }
381
382 if (!tune2fs_available()) {
383 LERROR << "Unable to enable ext4 encryption on " << blk_device
384 << " because " TUNE2FS_BIN " is missing";
385 return;
386 }
387
388 const char* argv[] = {TUNE2FS_BIN, "-Oencrypt", blk_device};
389
390 LINFO << "Enabling ext4 encryption on " << blk_device;
391 if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
392 LERROR << "Failed to run " TUNE2FS_BIN " to enable "
393 << "ext4 encryption on " << blk_device;
394 *fs_stat |= FS_STAT_ENABLE_ENCRYPTION_FAILED;
395 }
396}
397
398//
399// Prepare the filesystem on the given block device to be mounted.
400//
401// If the "check" option was given in the fstab record, or it seems that the
402// filesystem was uncleanly shut down, we'll run fsck on the filesystem.
403//
404// If needed, we'll also enable (or disable) filesystem features as specified by
405// the fstab record.
406//
407static int prepare_fs_for_mount(const char* blk_device, const struct fstab_rec* rec) {
408 int fs_stat = 0;
409
410 if (is_extfs(rec->fs_type)) {
411 struct ext4_super_block sb;
412
413 if (read_ext4_superblock(blk_device, &sb, &fs_stat)) {
414 if ((sb.s_feature_incompat & EXT4_FEATURE_INCOMPAT_RECOVER) != 0 ||
415 (sb.s_state & EXT4_VALID_FS) == 0) {
416 LINFO << "Filesystem on " << blk_device << " was not cleanly shutdown; "
417 << "state flags: 0x" << std::hex << sb.s_state << ", "
418 << "incompat feature flags: 0x" << std::hex << sb.s_feature_incompat;
419 fs_stat |= FS_STAT_UNCLEAN_SHUTDOWN;
422 } 420 }
421
422 // Note: quotas should be enabled before running fsck.
423 tune_quota(blk_device, rec, &sb, &fs_stat);
424 } else {
425 return fs_stat;
426 }
427 }
428
429 if ((rec->fs_mgr_flags & MF_CHECK) ||
430 (fs_stat & (FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED))) {
431 check_fs(blk_device, rec->fs_type, rec->mount_point, &fs_stat);
432 }
433
434 if (is_extfs(rec->fs_type) && (rec->fs_mgr_flags & (MF_RESERVEDSIZE | MF_FILEENCRYPTION))) {
435 struct ext4_super_block sb;
436
437 if (read_ext4_superblock(blk_device, &sb, &fs_stat)) {
438 tune_reserved_size(blk_device, rec, &sb, &fs_stat);
439 tune_encrypt(blk_device, rec, &sb, &fs_stat);
423 } 440 }
424 } 441 }
442
443 return fs_stat;
425} 444}
426 445
427static void remove_trailing_slashes(char *n) 446static void remove_trailing_slashes(char *n)
@@ -457,6 +476,16 @@ int fs_mgr_set_blk_ro(const char *blockdev)
457 return rc; 476 return rc;
458} 477}
459 478
479// Orange state means the device is unlocked, see the following link for details.
480// https://source.android.com/security/verifiedboot/verified-boot#device_state
481bool fs_mgr_is_device_unlocked() {
482 std::string verified_boot_state;
483 if (fs_mgr_get_boot_config("verifiedbootstate", &verified_boot_state)) {
484 return verified_boot_state == "orange";
485 }
486 return false;
487}
488
460/* 489/*
461 * __mount(): wrapper around the mount() system call which also 490 * __mount(): wrapper around the mount() system call which also
462 * sets the underlying block device to read-only if the mount is read-only. 491 * sets the underlying block device to read-only if the mount is read-only.
@@ -476,10 +505,11 @@ static int __mount(const char *source, const char *target, const struct fstab_re
476 if ((info.st_mode & S_IFMT) == S_IFLNK) 505 if ((info.st_mode & S_IFMT) == S_IFLNK)
477 unlink(target); 506 unlink(target);
478 mkdir(target, 0755); 507 mkdir(target, 0755);
508 errno = 0;
479 ret = mount(source, target, rec->fs_type, mountflags, rec->fs_options); 509 ret = mount(source, target, rec->fs_type, mountflags, rec->fs_options);
480 save_errno = errno; 510 save_errno = errno;
481 LINFO << __FUNCTION__ << "(source=" << source << ",target=" 511 PINFO << __FUNCTION__ << "(source=" << source << ",target=" << target
482 << target << ",type=" << rec->fs_type << ")=" << ret; 512 << ",type=" << rec->fs_type << ")=" << ret;
483 if ((ret == 0) && (mountflags & MS_RDONLY) != 0) { 513 if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
484 fs_mgr_set_blk_ro(source); 514 fs_mgr_set_blk_ro(source);
485 } 515 }
@@ -559,10 +589,7 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_
559 continue; 589 continue;
560 } 590 }
561 591
562 int fs_stat = 0; 592 int fs_stat = prepare_fs_for_mount(fstab->recs[i].blk_device, &fstab->recs[i]);
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) { 593 if (fs_stat & FS_STAT_EXT4_INVALID_MAGIC) {
567 LERROR << __FUNCTION__ << "(): skipping mount, invalid ext4, mountpoint=" 594 LERROR << __FUNCTION__ << "(): skipping mount, invalid ext4, mountpoint="
568 << fstab->recs[i].mount_point << " rec[" << i 595 << fstab->recs[i].mount_point << " rec[" << i
@@ -570,15 +597,6 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_
570 mount_errno = EINVAL; // continue bootup for FDE 597 mount_errno = EINVAL; // continue bootup for FDE
571 continue; 598 continue;
572 } 599 }
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 600
583 int retry_count = 2; 601 int retry_count = 2;
584 while (retry_count-- > 0) { 602 while (retry_count-- > 0) {
@@ -756,19 +774,6 @@ static int handle_encryptable(const struct fstab_rec* rec)
756 } 774 }
757} 775}
758 776
759// TODO: add ueventd notifiers if they don't exist.
760// This is just doing a wait_for_device for maximum of 1s
761int fs_mgr_test_access(const char *device) {
762 int tries = 25;
763 while (tries--) {
764 if (!access(device, F_OK) || errno != ENOENT) {
765 return 0;
766 }
767 usleep(40 * 1000);
768 }
769 return -1;
770}
771
772bool is_device_secure() { 777bool is_device_secure() {
773 int ret = -1; 778 int ret = -1;
774 char value[PROP_VALUE_MAX]; 779 char value[PROP_VALUE_MAX];
@@ -829,9 +834,7 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
829 } 834 }
830 835
831 /* Translate LABEL= file system labels into block devices */ 836 /* Translate LABEL= file system labels into block devices */
832 if (!strcmp(fstab->recs[i].fs_type, "ext2") || 837 if (is_extfs(fstab->recs[i].fs_type)) {
833 !strcmp(fstab->recs[i].fs_type, "ext3") ||
834 !strcmp(fstab->recs[i].fs_type, "ext4")) {
835 int tret = translate_ext_labels(&fstab->recs[i]); 838 int tret = translate_ext_labels(&fstab->recs[i]);
836 if (tret < 0) { 839 if (tret < 0) {
837 LERROR << "Could not translate label to block device"; 840 LERROR << "Could not translate label to block device";
@@ -839,8 +842,10 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
839 } 842 }
840 } 843 }
841 844
842 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { 845 if (fstab->recs[i].fs_mgr_flags & MF_WAIT &&
843 wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT); 846 !fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) {
847 LERROR << "Skipping '" << fstab->recs[i].blk_device << "' during mount_all";
848 continue;
844 } 849 }
845 850
846 if (fstab->recs[i].fs_mgr_flags & MF_AVB) { 851 if (fstab->recs[i].fs_mgr_flags & MF_AVB) {
@@ -1047,22 +1052,12 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
1047 } 1052 }
1048 1053
1049 /* First check the filesystem if requested */ 1054 /* First check the filesystem if requested */
1050 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { 1055 if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(n_blk_device, 20s)) {
1051 wait_for_file(n_blk_device, WAIT_TIMEOUT); 1056 LERROR << "Skipping mounting '" << n_blk_device << "'";
1057 continue;
1052 } 1058 }
1053 1059
1054 int fs_stat = 0; 1060 int fs_stat = prepare_fs_for_mount(n_blk_device, &fstab->recs[i]);
1055 int force_check = do_quota_with_shutdown_check(n_blk_device, fstab->recs[i].fs_type,
1056 &fstab->recs[i], &fs_stat);
1057
1058 if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) {
1059 check_fs(n_blk_device, fstab->recs[i].fs_type,
1060 fstab->recs[i].mount_point, &fs_stat);
1061 }
1062
1063 if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
1064 do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i], &fs_stat);
1065 }
1066 1061
1067 if (fstab->recs[i].fs_mgr_flags & MF_AVB) { 1062 if (fstab->recs[i].fs_mgr_flags & MF_AVB) {
1068 if (!avb_handle) { 1063 if (!avb_handle) {
@@ -1221,8 +1216,11 @@ int fs_mgr_swapon_all(struct fstab *fstab)
1221 fclose(zram_fp); 1216 fclose(zram_fp);
1222 } 1217 }
1223 1218
1224 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { 1219 if (fstab->recs[i].fs_mgr_flags & MF_WAIT &&
1225 wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT); 1220 !fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) {
1221 LERROR << "Skipping mkswap for '" << fstab->recs[i].blk_device << "'";
1222 ret = -1;
1223 continue;
1226 } 1224 }
1227 1225
1228 /* Initialize the swap area */ 1226 /* Initialize the swap area */