zoukankan      html  css  js  c++  java
  • 一个关于VTS VtsKernelCheckpointTest、VtsKernelCheckpointTest测项失败的代码分析

    如刚才实验,烧录GSI之后,本来已经被格式化为ext4的metadata分区,又被格式化为无格式的分区。

    我这边继续Check发现,在替换GSI的SOP中,fastboot –w选项如果在bootloader执行,会清userdata、cache、metadata分区为无格式分区,而后进入recovery再次格式化成ext4。

    FLOW如下:

    a. fastboot程序-w选项如果在loader中执行会传命令给loader清userdata,cache,metadata分区

    https://android.googlesource.com/platform/system/core/+/refs/heads/master/fastboot/fastboot.cpp

        if (wants_wipe) {
            if (force_flash) {
                CancelSnapshotIfNeeded();
            }
            std::vector<std::string> partitions = { "userdata", "cache", "metadata" };
            for (const auto& partition : partitions) {
                std::string partition_type;
                if (fb->GetVar("partition-type:" + partition, &partition_type) != fastboot::SUCCESS) {
                    continue;
                }
                if (partition_type.empty()) continue;
                fb->Erase(partition);
                if (partition == "userdata" && set_fbe_marker) {
                    fprintf(stderr, "setting FBE marker on initial userdata...
    ");
                    std::string initial_userdata_dir = create_fbemarker_tmpdir();
                    fb_perform_format(partition, 1, partition_type, "", initial_userdata_dir, fs_options);
                    delete_fbemarker_tmpdir(initial_userdata_dir);
                } else {
                    fb_perform_format(partition, 1, partition_type, "", "", fs_options);
                }
            }
        }

    b. bootloader根据fastboot传下的分区列表清除对应分区。

    c. recovery收到wipe=data会格式化userdata,cache,metadata分区为ext4格式.

    https://android.googlesource.com/platform/bootable/recovery/+/refs/heads/master/recovery.cpp

          case Device::WIPE_DATA:
            save_current_log = true;
            if (ui->IsTextVisible()) {
              if (ask_to_wipe_data(device)) {
                WipeData(device, false);
              }
            } else {
              WipeData(device, false);
              return Device::NO_ACTION;
            }
            break;

    但是目前的情况是做完fastboot –w选项之后,发现userdata,cache都被格式化为ext4格式,而metadata分区未被格式化,所以猜想recovery没有格式化metadata,

    进一步看code可以看到,recovery中如果要格式化metadata,需要volume_for_mount_point返回非空指针,

    https://android.googlesource.com/platform/bootable/recovery/+/refs/heads/master/install/wipe_data.cpp

    bool WipeData(Device* device, bool convert_fbe) {
      RecoveryUI* ui = device->GetUI();
      ui->Print("
    -- Wiping data...
    ");
      if (!FinishPendingSnapshotMerges(device)) {
        ui->Print("Unable to check update status or complete merge, cannot wipe partitions.
    ");
        return false;
      }
      bool success = device->PreWipeData();
      if (success) {
        success &= EraseVolume(DATA_ROOT, ui, convert_fbe);
        bool has_cache = volume_for_mount_point("/cache") != nullptr;
        if (has_cache) {
          success &= EraseVolume(CACHE_ROOT, ui, false);
        }
        if (volume_for_mount_point(METADATA_ROOT) != nullptr) {
          success &= EraseVolume(METADATA_ROOT, ui, false);
        }
      }
      if (success) {
        success &= device->PostWipeData();
      }
      ui->Print("Data wipe %s.
    ", success ? "complete" : "failed");
      return success;
    }

    而volume_for_mount_point调用GetEntryForMountPoint,根据entry.mount_point判断METADATA是否存在,如果存在就返回METADATA的挂载路径,

    然后EraseVolume函数会umount设备,再调用wipe_block_device清数据以及调用/system/bin/mke2fs格式化。

    https://android.googlesource.com/platform/bootable/recovery/+/refs/heads/master/install/wipe_data.cpp

    static bool EraseVolume(const char* volume, RecoveryUI* ui, bool convert_fbe) {
      bool is_cache = (strcmp(volume, CACHE_ROOT) == 0);
      bool is_data = (strcmp(volume, DATA_ROOT) == 0);
      ui->SetBackground(RecoveryUI::ERASING);
      ui->SetProgressType(RecoveryUI::INDETERMINATE);
      std::vector<saved_log_file> log_files;
      if (is_cache) {
        // If we're reformatting /cache, we load any past logs (i.e. "/cache/recovery/last_*") and the
        // current log ("/cache/recovery/log") into memory, so we can restore them after the reformat.
        log_files = ReadLogFilesToMemory();
      }
      ui->Print("Formatting %s...
    ", volume);
      ensure_path_unmounted(volume);
      int result;
      if (is_data && convert_fbe) {
        constexpr const char* CONVERT_FBE_DIR = "/tmp/convert_fbe";
        constexpr const char* CONVERT_FBE_FILE = "/tmp/convert_fbe/convert_fbe";
        // Create convert_fbe breadcrumb file to signal init to convert to file based encryption, not
        // full disk encryption.
        if (mkdir(CONVERT_FBE_DIR, 0700) != 0) {
          PLOG(ERROR) << "Failed to mkdir " << CONVERT_FBE_DIR;
          return false;
        }
        FILE* f = fopen(CONVERT_FBE_FILE, "wbe");
        if (!f) {
          PLOG(ERROR) << "Failed to convert to file encryption";
          return false;
        }
        fclose(f);
        result = format_volume(volume, CONVERT_FBE_DIR);
        remove(CONVERT_FBE_FILE);
        rmdir(CONVERT_FBE_DIR);
      } else {
        result = format_volume(volume);
      }
      if (is_cache) {
        RestoreLogFilesAfterFormat(log_files);
      }
      return (result == 0);
    }

    因为目前看到metadata未被格式化,因此有可能类entry中没有metadata分区相关信息,所以继续查找entry的fstab如何获取的,

    在fs_mgr_fstab.cpp中可以看到if(access(/system/bin/recovery, F_OK))表示当前是recovery启动,则读取recovery.fstab作为default_fstab_path。

    https://android.googlesource.com/platform/system/core/+/refs/heads/master/fs_mgr/fs_mgr_fstab.cpp

    // Loads the fstab file and combines with fstab entries passed in from device tree.
    bool ReadDefaultFstab(Fstab* fstab) {
        Fstab dt_fstab;
        ReadFstabFromDt(&dt_fstab, false);
        *fstab = std::move(dt_fstab);
        std::string default_fstab_path;
        // Use different fstab paths for normal boot and recovery boot, respectively
        if (access("/system/bin/recovery", F_OK) == 0) {
            default_fstab_path = "/etc/recovery.fstab";
        } else {  // normal boot
            default_fstab_path = GetFstabPath();
        }
        Fstab default_fstab;
        if (!default_fstab_path.empty()) {
            ReadFstabFromFile(default_fstab_path, &default_fstab);
        } else {
            LINFO << __FUNCTION__ << "(): failed to find device default fstab";
        }
        for (auto&& entry : default_fstab) {
            fstab->emplace_back(std::move(entry));
        }
        return !fstab->empty();
    }

    如果需要Check一下recovery.fstab中的内容,因为recovery.fstab是从在AN目录下打包过去的,所以在device下看到recovery有3张fstab,检查发现,3张表都是没有metadata分区的。

    所以要看一下这里加上metadata后是否可以。

  • 相关阅读:
    sqlserver 保留2位小数的写法
    Kettle 数据预览 乱码
    finereport 数据分析预览 居中 参数分割 自动查询
    Unable to locate value meta plugin of type (id)
    mysql8.0
    MySQL 搭建MHA高可用架构
    Java性能调优工具
    helm 部署etcd
    阿里云pv 使用
    ldconfig 引起的事故
  • 原文地址:https://www.cnblogs.com/smilingsusu/p/14032434.html
Copyright © 2011-2022 走看看