AndroidApex技术分析调研2-apexd执行流程分析

分析代码基线 android10-release

system\apex\apexd\apexd.rc
```rc
service apexd /system/bin/apexd
    class core
    critical
    user root
    group system
    shutdown critical

apexd执行流程分析

apexd源码入口system\apex\apexd\apexd_main.cpp

int main(int /*argc*/, char** argv) {
  // Use CombinedLogger to also log to the kernel log.
  android::base::InitLogging(argv, CombinedLogger());

  if (argv[1] != nullptr) {
    return HandleSubcommand(argv);
  }
  // TODO: add a -v flag or an external setting to change LogSeverity.
  android::base::SetMinimumLogSeverity(android::base::VERBOSE);

  android::apex::StatusOr<android::apex::VoldCheckpointInterface>
      vold_service_st = android::apex::VoldCheckpointInterface::Create();
  android::apex::VoldCheckpointInterface* vold_service = nullptr;
  if (!vold_service_st.Ok()) {
    LOG(ERROR) << "Could not retrieve vold service: "
               << vold_service_st.ErrorMessage();
  } else {
    vold_service = &*vold_service_st;
  }

  android::apex::onStart(vold_service);
  android::apex::binder::CreateAndRegisterService();
  android::apex::binder::StartThreadPool();

  // Notify other components (e.g. init) that all APEXs are correctly mounted
  // and are ready to be used. Note that it's important that the binder service
  // is registered at this point, since other system services might depend on
  // it.
  android::apex::onAllPackagesReady();

  android::apex::waitForBootStatus(
      android::apex::rollbackActiveSessionAndReboot,
      android::apex::unmountDanglingMounts);

  android::apex::binder::JoinThreadPool();
  return 1;
}

apexd\apexd_checkpoint_vold.cpp

  • 调用vold的supportsCheckpoint接口,检查当前文件系统是否支持checkpoint,设置VoldCheckpointInterface的supports_fs_checkpoints_
StatusOr<VoldCheckpointInterface> VoldCheckpointInterface::Create() {
  auto voldService =
      defaultServiceManager()->getService(android::String16("vold"));
  if (voldService != nullptr) {
    return StatusOr<VoldCheckpointInterface>(VoldCheckpointInterface(
        android::interface_cast<android::os::IVold>(voldService)));
  }
  return StatusOr<VoldCheckpointInterface>::Fail(
      "Failed to retrieve vold service.");
}

VoldCheckpointInterface::VoldCheckpointInterface(sp<IVold>&& vold_service) {
  vold_service_ = vold_service;
  supports_fs_checkpoints_ = false;
  android::binder::Status status =
      vold_service_->supportsCheckpoint(&supports_fs_checkpoints_);
  if (!status.isOk()) {
    LOG(ERROR) << "Failed to check if filesystem checkpoints are supported: "
               << status.toString8().c_str();
  }
}

android::apex::onStart

  • 设置kApexStatusSysprop(apexd.status)值为starting
  • 如果前面设置的VoldCheckpointInterface的supports_fs_checkpoints_为true,设置全局变量gSupportsFsCheckpoints为true
  • 如果SupportsFsCheckpoints为true,调用vold的needsCheckpoint检查当前是否在checkpoint模式
void onStart(CheckpointInterface* checkpoint_service) {
  LOG(INFO) << "Marking APEXd as starting";
  if (!android::base::SetProperty(kApexStatusSysprop, kApexStatusStarting)) {
    PLOG(ERROR) << "Failed to set " << kApexStatusSysprop << " to "
                << kApexStatusStarting;
  }

  if (checkpoint_service != nullptr) {
    gVoldService = checkpoint_service;
    StatusOr<bool> supports_fs_checkpoints =
        gVoldService->SupportsFsCheckpoints();
    if (supports_fs_checkpoints.Ok()) {
      gSupportsFsCheckpoints = *supports_fs_checkpoints;
    } else {
      LOG(ERROR) << "Failed to check if filesystem checkpoints are supported: "
                 << supports_fs_checkpoints.ErrorMessage();
    }
    if (gSupportsFsCheckpoints) {
      StatusOr<bool> needs_checkpoint = gVoldService->NeedsCheckpoint();
      if (needs_checkpoint.Ok()) {
        gInFsCheckpointMode = *needs_checkpoint;
      } else {
        LOG(ERROR) << "Failed to check if we're in filesystem checkpoint mode: "
                   << needs_checkpoint.ErrorMessage();
      }
    }
  }

  // Ask whether we should roll back any staged sessions; this can happen if
  // we've exceeded the retry count on a device that supports filesystem
  // checkpointing.
  if (gSupportsFsCheckpoints) {
    StatusOr<bool> needs_rollback = gVoldService->NeedsRollback();
    if (!needs_rollback.Ok()) {
      LOG(ERROR) << "Failed to check if we need a rollback: "
                 << needs_rollback.ErrorMessage();
    } else if (*needs_rollback) {
      LOG(INFO) << "Exceeded number of session retries ("
                << kNumRetriesWhenCheckpointingEnabled
                << "). Starting a rollback";
      Status status = rollbackStagedSessionIfAny();
      if (!status.Ok()) {
        LOG(ERROR)
            << "Failed to roll back (as requested by fs checkpointing) : "
            << status.ErrorMessage();
      }
    }
  }

  Status status = collectApexKeys();
  if (!status.Ok()) {
    LOG(ERROR) << "Failed to collect APEX keys : " << status.ErrorMessage();
    return;
  }

  gMountedApexes.PopulateFromMounts();

  // Activate APEXes from /data/apex. If one in the directory is newer than the
  // system one, the new one will eclipse the old one.
  scanStagedSessionsDirAndStage();
  status = resumeRollbackIfNeeded();
  if (!status.Ok()) {
    LOG(ERROR) << "Failed to resume rollback : " << status.ErrorMessage();
  }

  status = scanPackagesDirAndActivate(kActiveApexPackagesDataDir);
  if (!status.Ok()) {
    LOG(ERROR) << "Failed to activate packages from "
               << kActiveApexPackagesDataDir << " : " << status.ErrorMessage();
    Status rollback_status = rollbackActiveSessionAndReboot();
    if (!rollback_status.Ok()) {
      // TODO: should we kill apexd in this case?
      LOG(ERROR) << "Failed to rollback : " << rollback_status.ErrorMessage();
    }
  }

  for (const auto& dir : kApexPackageBuiltinDirs) {
    // TODO(b/123622800): if activation failed, rollback and reboot.
    status = scanPackagesDirAndActivate(dir.c_str());
    if (!status.Ok()) {
      // This should never happen. Like **really** never.
      // TODO: should we kill apexd in this case?
      LOG(ERROR) << "Failed to activate packages from " << dir << " : "
                 << status.ErrorMessage();
    }
  }
}
posted @ 2023-02-19 15:24  leo21sun  阅读(557)  评论(0编辑  收藏  举报