• Android Framework 常见解决方案(23)三方应用APP启动绑核setAffinity设置


    1 原理解读

    一般来说这个需求主要是为了应用启动时设定绑核相关操作,但是如果没有三方应用的源码想要让其绑定再其他核心上就要修改framework源码了。framework源码修改的原理是:在zygote创建应用子进程(Fork操作)时做白名单处理,针对不同的应用APP进程进行可以有不同的绑核策略。关于Zygote的初始化以及创建APP进程的流程这里就不多说了,最终创建进程回调用到这里:com_android_internal_os_Zygote.cpp中的
    com_android_internal_os_Zygote_nativeForkAndSpecialize方法。代码实现如下:

    1. com_android_internal_os_Zygote_nativeForkAndSpecialize(...){
    2. //...
    3. if (pid == 0) {
    4. SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, capabilities, capabilities,
    5. mount_external, se_info, nice_name, false, is_child_zygote == JNI_TRUE,
    6. instruction_set, app_data_dir, is_top_app == JNI_TRUE, pkg_data_info_list,
    7. allowlisted_data_info_list, mount_data_dirs == JNI_TRUE,
    8. mount_storage_dirs == JNI_TRUE);
    9. }
    10. //...
    11. }

    2 修改方案(Android Q R S)

    修改文件为:AOSP/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp,这里主要给出了3个应用xxx1、xxx2、xxx3,绑核策略分别为7,456,234,根据此需求,具体修改内容为:

    1. // Utility routine to specialize a zygote child process.
    2. static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags,
    3. jobjectArray rlimits, jlong permitted_capabilities,
    4. jlong effective_capabilities, jint mount_external,
    5. jstring managed_se_info, jstring managed_nice_name,
    6. bool is_system_server, bool is_child_zygote,
    7. jstring managed_instruction_set, jstring managed_app_data_dir,
    8. bool is_top_app, jobjectArray pkg_data_info_list,
    9. jobjectArray allowlisted_data_info_list, bool mount_data_dirs,
    10. bool mount_storage_dirs) {
    11. const char* process_name = is_system_server ? "system_server" : "zygote";
    12. auto fail_fn = std::bind(ZygoteFailure, env, process_name, managed_nice_name, _1);
    13. auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1);
    14. auto se_info = extract_fn(managed_se_info);
    15. auto nice_name = extract_fn(managed_nice_name);
    16. auto instruction_set = extract_fn(managed_instruction_set);
    17. auto app_data_dir = extract_fn(managed_app_data_dir);
    18. // Keep capabilities across UID change, unless we're staying root.
    19. if (uid != 0) {
    20. EnableKeepCapabilities(fail_fn);
    21. }
    22. SetInheritable(permitted_capabilities, fail_fn);
    23. DropCapabilitiesBoundingSet(fail_fn);
    24. //...
    25. const char* se_info_ptr = se_info.has_value() ? se_info.value().c_str() : nullptr;
    26. const char* nice_name_ptr = nice_name.has_value() ? nice_name.value().c_str() : nullptr;
    27. if (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) {
    28. fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed", uid,
    29. is_system_server, se_info_ptr, nice_name_ptr));
    30. }
    31. // Make it easier to debug audit logs by setting the main thread's name to the
    32. // nice name rather than "app_process".
    33. if (nice_name.has_value()) {
    34. SetThreadName(nice_name.value());
    35. + //xxx1应用绑定核心7
    36. + if(strncmp(nice_name.value().c_str(),"com.xxx.xxx1",sizeof("com.xxx.xxx1"))==0){
    37. + cpu_set_t mask;
    38. + CPU_ZERO(&mask);
    39. + CPU_SET(7, &mask);
    40. + int ret = sched_setaffinity(0, sizeof(mask), &mask);
    41. + if (ret != 0) {
    42. + ALOGE("xxx1,setSchedAffinity call failure,ret:%d,(%s)", ret,nice_name.value().c_str());
    43. + }else{
    44. + ALOGE("xxx1,setSchedAffinity call success,ret==0,(%s)", nice_name.value().c_str());
    45. + }
    46. + }
    47. + //xxx2应用绑定核心4、5、6
    48. + if(strncmp(nice_name.value().c_str(),"com.xxx.xxx2",sizeof("com.xxx.xxx2"))==0){
    49. + cpu_set_t mask;
    50. + CPU_ZERO(&mask);
    51. + CPU_SET(6, &mask);
    52. + CPU_SET(5, &mask);
    53. + CPU_SET(4, &mask);
    54. + int ret = sched_setaffinity(0, sizeof(mask), &mask);
    55. + if (ret != 0) {
    56. + ALOGE("xxx2,setSchedAffinity call failure,ret:%d,(%s)", ret,nice_name.value().c_str());
    57. + }else{
    58. + ALOGE("xxx2,setSchedAffinity call success,ret==0,(%s)", nice_name.value().c_str());
    59. + }
    60. + }
    61. + //xxx3应用绑定核心2、3、4
    62. + if(strncmp(nice_name.value().c_str(),"com.xxx.xxx3",sizeof("com.xxx.xxx3"))==0){
    63. + cpu_set_t mask;
    64. + CPU_ZERO(&mask);
    65. + CPU_SET(4, &mask);
    66. + CPU_SET(3, &mask);
    67. + CPU_SET(2, &mask);
    68. + int ret = sched_setaffinity(0, sizeof(mask), &mask);
    69. + if (ret != 0) {
    70. + ALOGE("xxx3,setSchedAffinity call failure,ret:%d,(%s)", ret,nice_name.value().c_str());
    71. + }else{
    72. + ALOGE("xxx3,setSchedAffinity call success,ret==0,(%s)", nice_name.value().c_str());
    73. + }
    74. + }
    75. } else if (is_system_server) {
    76. SetThreadName("system_server");
    77. }
    78. // Unset the SIGCHLD handler, but keep ignoring SIGHUP (rationale in SetSignalHandlers).
    79. UnsetChldSignalHandler();
    80. if (is_system_server) {
    81. env->CallStaticVoidMethod(gZygoteClass, gCallPostForkSystemServerHooks, runtime_flags);
    82. if (env->ExceptionCheck()) {
    83. fail_fn("Error calling post fork system server hooks.");
    84. }
    85. // TODO(b/117874058): Remove hardcoded label here.
    86. static const char* kSystemServerLabel = "u:r:system_server:s0";
    87. if (selinux_android_setcon(kSystemServerLabel) != 0) {
    88. fail_fn(CREATE_ERROR("selinux_android_setcon(%s)", kSystemServerLabel));
    89. }
    90. }
    91. if (is_child_zygote) {
    92. initUnsolSocketToSystemServer();
    93. }
    94. env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
    95. is_system_server, is_child_zygote, managed_instruction_set);
    96. // Reset the process priority to the default value.
    97. setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT);
    98. if (env->ExceptionCheck()) {
    99. fail_fn("Error calling post fork hooks.");
    100. }
    101. }

  • 相关阅读:
    【数据处理】建立数据库索引并定时重建索引
    计算机网络 | 第三章 数据链路层 | 王道考研自用笔记
    Feign源码解析:初始化过程(二)
    热门好用的API分享,含免费次数
    六、循环表达式
    Linux 进程概念
    2024年端午节放假通知
    Android 使用FFmpeg3.3.9基于命令实现视频压缩
    Windows11轻松设置v1.06绿色版
    个人网页设计成品DW静态网页 HTML网页设计结课作业 web课程设计网页规划与设计 Web大学生个人网页成品 web网页设计期末课程大作业
  • 原文地址:https://blog.csdn.net/vviccc/article/details/133799580