首页 > 其他分享 >AndroidApex技术分析调研2-apexd执行流程分析

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

时间:2023-02-19 15:35:49浏览次数:47  
标签:分析 vold apexd service AndroidApex checkpoints android VoldCheckpointInterface

分析代码基线 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();
    }
  }
}

标签:分析,vold,apexd,service,AndroidApex,checkpoints,android,VoldCheckpointInterface
From: https://www.cnblogs.com/codeking100/p/17134810.html

相关文章

  • 信号分析与处理相关概念
    自协方差矩阵(AutocovarianceMatrix):是指一个信号在不同时刻的自协方差所构成的矩阵,通常用来描述随机信号的统计特性。功率谱密度(PowerSpectralDensity,PSD):是指信号......
  • 【MySQL-索引:分类,语法,性能分析,使用,设计原则】
    零、本文纲要一、索引概述二、索引分类三、索引语法四、SQL性能分析五、索引使用六、索引设计原则tips:Ctrl+F快速定位到所需内容阅读吧。一、索引概述索引(index)是帮助MySQ......
  • 漏洞分析-log4j RCE-JAVA篇
    0x00原理分析log4j的介绍:log4j是java打印输出日志的一个API,只要引入了log4j的jar包或者是在xml配置文件内配置好log4j即可输入java运行时产生的日志内容,一般用于记录网......
  • 对交换环的局部化的相关分析
    定义一般形式的分数集合以及其上的加法和乘法运算得到的结构 (F,+,·)(R,+,·)是一个交换环,S是R的一个乘法子集(即S是R\{0}的乘法子幺半群),定义集合F={r......
  • 漏洞分析-存储型XSS-JAVA篇
    0x00原理分析存储型XSS:用户在浏览器传入的数据未做校验,导致一些恶意的前端代码被插入至数据库中,前端再次读取数据时,数据被当成前端代码,或与前端代码拼接并执行。0x01效......
  • 【Spring IOC】【七】容器源码解析- PostConstruct、PreDestory的源码分析
    1 前言@PostConstruct、@PreDestory这两个注解大家应该有用过吧,我们这篇分析一下主要是PostConstruct这个注解的解析时机和执行时机。2 源码分析2.1 解析时机-doC......
  • 【Kotlin】函数式编程 ③ ( 早集合与惰性集合 | 惰性集合-序列 | generateSequence 序
    文章目录​​一、及早集合与惰性集合​​​​二、惰性集合-序列​​​​三、generateSequence序列创建函数​​​​1、函数简介​​​​2、函数原型​​​​3、函数简介​......
  • 大数据分析———(3)数据清洗
    3.3.1在Eclipse创建代码文件在项目上右键==>New==>ScalaObject,进入spark文件的创建菜单设置包名.类名后点击Finish创建成功 3.3.2代码文件书写与运行完整代码......
  • 大数据分析———(4)数据分析
    我们采用hive数据仓库,把上面用Spark清洗完成的数据进行数据的存储与分析。3.4.1Hive的启动与数据上传首先在Linux终端界面任意目录下输入hiveshell进入hives......
  • 大数据分析———(2)准备工作
    3.2.1环境安装本次项目使用Spark进行数据清洗,首先需要安装Scala环境。下载解压后,修改~/.bashrc文件,把Scala添加到系统环境变量中。3.2.2环境运行在启动Spark之前,首......