MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
2291 int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
2292 int error_count = 0;
2293 CheckpointManager checkpoint_manager;
2294 //zhoumaowei@Android.storage,2022/02/18, add for skip mount userdata in ffbm mode
2295 char propbuf[PROPERTY_VALUE_MAX];
2296 char propbuf_buid_type[PROPERTY_VALUE_MAX];
2297
2298 bool is_ffbm = false;
2299 AvbUniquePtr avb_handle(nullptr);
2300 bool wiped = false;
2301
2302 bool userdata_mounted = false;
2303 if (fstab->empty()) {
2304 return {FS_MGR_MNTALL_FAIL, userdata_mounted};
2305 }
2306 //zhoumaowei@Android.storage,2022/02/18, add for skip mount userdata in ffbm mode
2307 /**get boot mode*/
2308 property_get("ro.bootmode", propbuf, "");
2309 property_get("ro.build.type", propbuf_buid_type, "");
2310 if (((strncmp(propbuf, "ffbm-00", 7) == 0) || (strncmp(propbuf, "ffbm-01", 7) == 0)) &&
2311 ((strncmp(propbuf_buid_type, "eng", 3) == 0) || (strncmp(propbuf_buid_type, "userdebug", 9) == 0)))
2312 is_ffbm = true;
2313
2314 bool scratch_can_be_mounted = true;
2315
2316 // Keep i int to prevent unsigned integer overflow from (i = top_idx - 1),
2317 // where top_idx is 0. It will give SIGABRT
2318 for (int i = 0; i < static_cast<int>(fstab->size()); i++) {
2319 auto& current_entry = (*fstab)[i];
2320 //zhoumaowei@Android.storage,2022/02/18, add for skip mount userdata in ffbm mode
2321 /* Skip userdata partition in ffbm mode */
2322 if (is_ffbm && !strcmp(current_entry.mount_point.c_str(), "/data")){
2323 continue;
2324 }
2325
2326 // If a filesystem should have been mounted in the first stage, we
2327 // ignore it here. With one exception, if the filesystem is
2328 // formattable, then it can only be formatted in the second stage,
2329 // so we allow it to mount here.
2330 if (current_entry.fs_mgr_flags.first_stage_mount &&
2331 (!current_entry.fs_mgr_flags.formattable ||
2332 IsMountPointMounted(current_entry.mount_point))) {
2333 continue;
2334 }
2335
2336 // Don't mount entries that are managed by vold or not for the mount mode.
2337 if (current_entry.fs_mgr_flags.vold_managed || current_entry.fs_mgr_flags.recovery_only ||
2338 ((mount_mode == MOUNT_MODE_LATE) && !current_entry.fs_mgr_flags.late_mount) ||
2339 ((mount_mode == MOUNT_MODE_EARLY) && current_entry.fs_mgr_flags.late_mount)) {
2340 continue;
2341 }
2342
2343 // Skip swap and raw partition entries such as boot, recovery, etc.
2344 if (current_entry.fs_type == "swap" || current_entry.fs_type == "emmc" ||
2345 current_entry.fs_type == "mtd") {
2346 continue;
2347 }
2348
2349 // Skip mounting the root partition, as it will already have been mounted.
2350 if (current_entry.mount_point == "/" || current_entry.mount_point == "/system") {
2351 if ((current_entry.flags & MS_RDONLY) != 0) {
2352 fs_mgr_set_blk_ro(current_entry.blk_device);
2353 }
2354 continue;
2355 }
2356
2357 // Terrible hack to make it possible to remount /data.
2358 // TODO: refactor fs_mgr_mount_all and get rid of this.
2359 if (mount_mode == MOUNT_MODE_ONLY_USERDATA && current_entry.mount_point != "/data") {
2360 continue;
2361 }
2362
2363 // Translate LABEL= file system labels into block devices.
2364 if (is_extfs(current_entry.fs_type)) {
2365 if (!TranslateExtLabels(¤t_entry)) {
2366 LERROR << "Could not translate label to block device";
2367 continue;
2368 }
2369 }
2370
2371 if (current_entry.fs_mgr_flags.logical) {
2372 if (!fs_mgr_update_logical_partition(¤t_entry)) {
2373 LERROR << "Could not set up logical partition, skipping!";
2374 continue;
2375 }
2376 }
2377
2378 WrapUserdataIfNeeded(¤t_entry);
2379
2380 if (!checkpoint_manager.Update(¤t_entry)) {
2381 continue;
2382 }
2383
2384 #ifdef OPLUS_FEATURE_STORAGE_MOUNT
2385 //#Xuefeng.Peng@ANDROID.STORAGE, 2020/08/17, Add for upgrade project mount special_preload
2386 if ((current_entry.mount_point != "/special_preload") && current_entry.fs_mgr_flags.wait && !WaitForFile(current_entry.blk_device, 20s)) {
2387 #else
2388 if (current_entry.fs_mgr_flags.wait && !WaitForFile(current_entry.blk_device, 20s)) {
2389 #endif
2390 LERROR << "Skipping '" << current_entry.blk_device << "' during mount_all";
2391 continue;
2392 }
2393
2394 /*feature-resize-v001-5-begin*/
2395 //#Xuefeng.Peng@ANDROID.STORAGE.0, 2019/04/19, Add for android Q support resize
2396 #ifdef OPLUS_FEATURE_STORAGE_RESIZE
2397 if(current_entry.fs_mgr_flags.resize) {
2398 int fs_stat = 0;
2399 save_log("%s:%d fs_mgr_mount_all run-check_fs and resize_fs blk_dev=%s fs_type=%s mount_point=%s",__FUNCTION__, __LINE__,current_entry.blk_device.c_str(), current_entry.fs_type.c_str(),current_entry.mount_point.c_str());
2400
2401 check_fs(current_entry.blk_device, current_entry.fs_type, current_entry.mount_point, &fs_stat);
2402 resize_fs(current_entry.blk_device.c_str(), current_entry.fs_type.c_str());
2403 }
2404 #endif
2405 /*feature-resize-v001-5-end*/
2406
2407 if (current_entry.fs_mgr_flags.avb) {
2408 if (!avb_handle) {
2409 avb_handle = AvbHandle::Open();
2410 if (!avb_handle) {
2411 LERROR << "Failed to open AvbHandle";
2412 set_type_property(encryptable);
2413 return {FS_MGR_MNTALL_FAIL, userdata_mounted};
2414 }
2415 }
2416 if (avb_handle->SetUpAvbHashtree(¤t_entry, true /* wait_for_verity_dev */) ==
2417 AvbHashtreeResult::kFail) {
2418 LERROR << "Failed to set up AVB on partition: " << current_entry.mount_point
2419 << ", skipping!";
2420 // Skips mounting the device.
2421 continue;
2422 }
2423 } else if (!current_entry.avb_keys.empty()) {
2424 if (AvbHandle::SetUpStandaloneAvbHashtree(¤t_entry) == AvbHashtreeResult::kFail) {
2425 LERROR << "Failed to set up AVB on standalone partition: "
2426 << current_entry.mount_point << ", skipping!";
2427 // Skips mounting the device.
2428 continue;
2429 }
2430 }
2431
2432 int last_idx_inspected;
2433 int top_idx = i;
2434 int attempted_idx = -1;
2435
2436 bool mret = mount_with_alternatives(*fstab, i, &last_idx_inspected, &attempted_idx);
2437 auto& attempted_entry = (*fstab)[attempted_idx];
2438 i = last_idx_inspected;
2439 int mount_errno = errno;
2440
2441 // Handle success and deal with encryptability.
2442 if (mret) {
2443 #ifdef OPLUS_FEATURE_STORAGE_MOUNT
2444 //Xuefeng.Peng@PSW.AD.Storage.0, 2019/06/06, Add for save log
2445 save_log("%s:%d mount_with_alternatives end true, mount_point=%s, error=%s",__FUNCTION__, __LINE__, attempted_entry.mount_point.c_str(), strerror(mount_errno));
2446
2447 #endif
2448 int status = handle_encryptable(attempted_entry);
2449
2450 if (status == FS_MGR_MNTALL_FAIL) {
2451 // Fatal error - no point continuing.
2452 return {status, userdata_mounted};
2453 }
2454
2455 if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
2456 save_log("--------------Sencond_stage_mount_late-first_start-encryptfstab_userdata-------------------");
2457 if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
2458 // Log and continue
2459 LERROR << "Only one encryptable/encrypted partition supported";
2460 }
2461 encryptable = status;
2462 if (status == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
2463 fs_mgr_set_blk_ro(attempted_entry.blk_device, false);
2464 if (!call_vdc({"cryptfs", "encryptFstab", attempted_entry.blk_device,
2465 attempted_entry.mount_point, wiped ? "true" : "false",
2466 attempted_entry.fs_type,
2467 attempted_entry.fs_mgr_flags.is_zoned ? "true" : "false",
2468 android::base::Join(attempted_entry.user_devices, ' ')},
2469 nullptr)) {
2470 LERROR << "Encryption failed";
2471 set_type_property(encryptable);
2472 return {FS_MGR_MNTALL_FAIL, userdata_mounted};
2473 }
2474 }
2475 }
2476
2477 if (current_entry.mount_point == "/data") {
2478 userdata_mounted = true;
2479 }
2480
2481 MountOverlayfs(attempted_entry, &scratch_can_be_mounted);
2482
2483 // Success! Go get the next one.
2484 continue;
2485 }
2486
2487 // Mounting failed, understand why and retry.
2488 wiped = partition_wiped(current_entry.blk_device.c_str());
2489 if (mount_errno != EBUSY && mount_errno != EACCES &&
2490 current_entry.fs_mgr_flags.formattable && wiped) {
2491 // current_entry and attempted_entry point at the same partition, but sometimes
2492 // at two different lines in the fstab. Use current_entry for formatting
2493 // as that is the preferred one.
2494 LERROR << __FUNCTION__ << "(): " << realpath(current_entry.blk_device)
2495 << " is wiped and " << current_entry.mount_point << " " << current_entry.fs_type
2496 << " is formattable. Format it.";
2497 #ifdef OPLUS_FEATURE_STORAGE_MOUNT
2498 //Xuefeng.Peng@PSW.AD.Storage.0, 2019/06/06, Add for save log
2499 save_log("%s:%d blk_dev=%s is wiped and mount_point=%s fs_type=%s is formattable. Format it.error=%s",__FUNCTION__, __LINE__, realpath(current_entry.blk_device).c_str(), current_entry.mount_point.c_str(), current_entry.fs_type.c_str(), strerror(mount_errno));
2500
2501 #endif
2502 checkpoint_manager.Revert(¤t_entry);
2503
2504
2505 // EncryptInplace will be used when vdc gives an error or needs to format partitions
2506 // other than /data
2507 /*feature-nonencryptforfactory-v001-2-begin*/
2508 #ifndef OPLUS_FEATURE_STORAGE_MOUNT
2509 //Xuefeng.Peng@PSW.AD.Storage.DiskEncryption.1962356, 2019/04/18, Add for not real battery, do not use metadta encrypt
2510 if (should_use_metadata_encryption(current_entry) &&
2511 #else
2512 if (should_use_metadata_encryption(current_entry) && (cryptfs_check_battery_state() == 1) &&
2513 #endif/*OPLUS_FEATURE_STORAGE_MOUNT*/
2514 /*feature-nonencryptforfactory-v001-2-end*/
2515 current_entry.mount_point == "/data") {
2516
2517 // vdc->Format requires "ro.crypto.type" to set an encryption flag
2518 encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED;
2519 set_type_property(encryptable);
2520
2521 if (!call_vdc({"cryptfs", "encryptFstab", current_entry.blk_device,
2522 current_entry.mount_point, "true" /* shouldFormat */,
2523 current_entry.fs_type,
2524 current_entry.fs_mgr_flags.is_zoned ? "true" : "false",
2525 android::base::Join(current_entry.user_devices, ' ')},
2526 nullptr)) {
2527 LERROR << "Encryption failed";
2528 } else {
2529 userdata_mounted = true;
2530 continue;
2531 }
2532 }
2533
2534 if (fs_mgr_do_format(current_entry) == 0) {
2535 // Let's replay the mount actions.
2536 i = top_idx - 1;
2537 continue;
2538 } else {
2539 LERROR << __FUNCTION__ << "(): Format failed. "
2540 << "Suggest recovery...";
2541 #ifdef OPLUS_FEATURE_STORAGE_MOUNT
2542 //Xuefeng.Peng@PSW.AD.Storage.0, 2019/06/06, Add for save lo
2543 save_log("%s:%d Format failed. Suggest recovery...,FS_MGR_MNTALL_DEV_NEEDS_RECOVERY, mount_point=%s,error=%s",__FUNCTION__, __LINE__, current_entry.mount_point.c_str(), strerror(mount_errno));
2544
2545 #endif
2546 encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
2547 continue;
2548 }
2549 }
2550
2551 // mount(2) returned an error, handle the encryptable/formattable case.
2552
2553 /*feature-nonencryptforfactory-v001-3-begin*/
2554 #ifndef OPLUS_FEATURE_STORAGE_MOUNT
2555 //Xuefeng.Peng@PSW.AD.Storage.DiskEncryption.1962356, 2019/04/18, Add for not real battery, do not use metadta encrypt
2556 if (mount_errno != EBUSY && mount_errno != EACCES &&
2557 should_use_metadata_encryption(attempted_entry)) {
2558 #else
2559 if (mount_errno != EBUSY && mount_errno != EACCES &&
2560 should_use_metadata_encryption(attempted_entry) && (cryptfs_check_battery_state() == 1)) {
2561 #endif/*OPLUS_FEATURE_STORAGE_MOUNT*/
2562 /*feature-nonencryptforfactory-v001-3-end*/
2563 save_log("--------------Sencond_stage_mount_late-second_start-------------------");
2564 if (!call_vdc({"cryptfs", "mountFstab", attempted_entry.blk_device,
2565 attempted_entry.mount_point,
2566 current_entry.fs_mgr_flags.is_zoned ? "true" : "false",
2567 android::base::Join(current_entry.user_devices, ' ')},
2568 nullptr)) {
2569 #ifdef OPLUS_FEATURE_STORAGE_MOUNT
2570 //Xuefeng.Peng@PSW.AD.Storage.0, 2019/06/06, Add for save log
2571 save_log("%s:%d Failure while mounting metadata, setting flag to needing recovery, mount_point=%s",__FUNCTION__, __LINE__, attempted_entry.mount_point.c_str());
2572
2573 #endif
2574 //#ifdef SOC_COMMON_QCOM
2575 //#zhoumaowei@Android.storage,2022/02/18 add for recovery when mounting metadata failed
2576 PERROR << android::base::StringPrintf(
2577 "Failure while mounting metadata, setting flag to needing recovery "
2578 "partition on %s at %s options: %s",
2579 attempted_entry.blk_device.c_str(), attempted_entry.mount_point.c_str(),
2580 attempted_entry.fs_options.c_str());
2581 encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY_WIPE_PROMPT;
2582 //#else
2583 //++error_count;
2584 //#endif /*SOC_COMMON_QCOM*/
2585 } else if (current_entry.mount_point == "/data") {
2586 userdata_mounted = true;
2587 }
2588 #ifdef OPLUS_FEATURE_STORAGE_MOUNT
2589 //Xuefeng.Peng@PSW.AD.Storage.0, 2019/06/06, Add for save log
2590 save_log("%s:%d encrypted = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED, mount_point=%s",__FUNCTION__, __LINE__, attempted_entry.mount_point.c_str());
2591
2592 #endif
2593 encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED;
2594 continue;
2595 } else {
2596 // fs_options might be null so we cannot use PERROR << directly.
2597 // Use StringPrintf to output "(null)" instead.
2598 if (attempted_entry.fs_mgr_flags.no_fail) {
2599 PERROR << android::base::StringPrintf(
2600 "Ignoring failure to mount an un-encryptable or wiped "
2601 "partition on %s at %s options: %s",
2602 attempted_entry.blk_device.c_str(), attempted_entry.mount_point.c_str(),
2603 attempted_entry.fs_options.c_str());
2604 } else {
2605 PERROR << android::base::StringPrintf(
2606 "Failed to mount an un-encryptable or wiped partition "
2607 "on %s at %s options: %s",
2608 attempted_entry.blk_device.c_str(), attempted_entry.mount_point.c_str(),
2609 attempted_entry.fs_options.c_str());
2610 #ifdef OPLUS_FEATURE_STORAGE_MOUNT
2611 //#Xuefeng.Peng@ANDROID.STORAGE, 2020/08/17, Add for upgrade project mount special_preload
2612 if (current_entry.mount_point == "/special_preload") {
2613 save_log("ignore special_preload mount error");
2614 } else {
2615 ++error_count;
2616 }
2617 #else
2618 ++error_count;
2619 #endif/*OPLUS_FEATURE_STORAGE_MOUNT*/
2620 }
2621 continue;
2622 }
2623 }
2624 if (userdata_mounted) {
2625 Fstab mounted_fstab;
2626 if (!ReadFstabFromFile("/proc/mounts", &mounted_fstab)) {
2627 LOG(ERROR) << "Could't load fstab from /proc/mounts , unable to set ro.fstype.data . "
2628 "init.rc actions depending on this prop would not run, boot might fail.";
2629 } else {
2630 for (const auto& entry : mounted_fstab) {
2631 if (entry.mount_point == "/data") {
2632 android::base::SetProperty("ro.fstype.data", entry.fs_type);
2633 }
2634 }
2635 }
2636 }
2637
2638 set_type_property(encryptable);
2639
2640 if (error_count) {
2641 return {FS_MGR_MNTALL_FAIL, userdata_mounted};
2642 } else {
2643 return {encryptable, userdata_mounted};
2644 }
2645 }