لایه انتزاعی گروه کنترل

‫Android 10 و نسخه‌های بالاتر از لایه انتزاعی گروه کنترل (cgroup) با نمایه‌های تکلیف استفاده می‌کنند که توسعه‌دهندگان می‌توانند از آن برای توصیف مجموعه‌ای (یا مجموعه‌هایی) از محدودیت‌ها برای اعمال روی رشته یا فرایند استفاده کنند. سپس سیستم کنش‌های تجویز‌شده نمایه‌های تکلیف را دنبال می‌کند تا یک یا چند گروه کنترل مناسب را انتخاب کند که ازطریق آن‌ها محدودیت‌ها اعمال می‌شوند و تغییرات در مجموعه ویژگی‌های گروه کنترل زیرین می‌تواند بدون تأثیر بر لایه‌های نرم‌افزاری بالاتر انجام شود.

درباره cgroups

گروه‌های کنترل سازوکاری برای تجمیع و تقسیم مجموعه‌های وظایف (که شامل فرایندها، رشته‌ها، و همه فرزندان آینده آن‌ها می‌شود) در گروه‌های سلسله‌مراتبی با رفتار تخصصی ارائه می‌دهند. ‫Android از cgroups برای کنترل و حسابرسی منابع سیستم مثل استفاده و تخصیص واحد پردازش مرکزی و حافظه استفاده می‌کند و از هسته Linux cgroups v1 و cgroups v2 پشتیبانی می‌کند.

‫Android 9 و نسخه‌های پایین‌تر

در Android 9 و نسخه‌های پایین‌تر، اسکریپت مقداردهی اولیه init.rc شامل مجموعه‌ای از cgroupهای دردسترس، نقاط نصب، و نسخه‌های آن‌ها بود. هرچند این‌ها قابل‌تغییر بودند، چارچوب Android انتظار داشت که مجموعه خاصی از cgroupها در مکان‌های خاصی با نسخه و سلسله‌مراتب زیرگروه خاصی، براساس اسکریپت، وجود داشته باشند. این امر توانایی انتخاب نسخه بعدی گروه کنترل برای استفاده یا تغییر سلسله‌مراتب گروه کنترل برای استفاده از ویژگی‌های جدید را محدود می‌کرد.

‫Android 10 و بالاتر

‫Android 10 و نسخه‌های بالاتر از cgroups با نمایه‌های تکلیف استفاده می‌کنند:

  • راه‌اندازی Cgroup. توسعه‌دهندگان راه‌اندازی cgroups را در فایل cgroups.json خود شرح می‌دهند تا مجموعه‌های cgroups و مکان‌های سوار کردن و مشخصه‌های آن‌ها را تعریف کنند. همه گروه‌های کنترل در مرحله اولیه راه‌اندازی فرایند راه‌اندازی نصب می‌شوند.
  • نمایه‌های تکلیف. این‌ها انتزاعی را ارائه می‌دهند که عملکرد موردنیاز را از جزئیات پیاده‌سازی آن جدا می‌کند. چارچوب Android نمایه‌های تکلیف را همان‌گونه که در فایل task_profiles.json توضیح داده شده است به فرایند یا رشته‌ای بااستفاده از میاناهای برنامه‌سازی کاربردی SetTaskProfiles و SetProcessProfiles اعمال می‌کند. (این میاناهای برنامه‌سازی کاربردی مختص Android 11 و بالاتر است.)

برای ارائه سازگاری با نسخه قدیمی، عملکردهای قدیمی set_cpuset_policy، set_sched_policy، و get_sched_policy همان میانای برنامه‌سازی کاربردی و عملکرد را ارائه می‌دهند، اما پیاده‌سازی آن‌ها برای استفاده از نمایه‌های تکلیف اصلاح شده است. برای موارد استفاده جدید، ‫AOSP توصیه می‌کند به‌جای تابع قدیمی set_sched_policy از میاناهای برنامه‌سازی کاربردی نمایه وظیفه جدید استفاده کنید.

فایل شرح Cgroups

گروه‌های کنترل در فایل cgroups.json واقع در <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/ شرح داده شده است. هر کنترل‌کننده در یک بخش فرعی توصیف می‌شود و باید حداقل موارد زیر را داشته باشد:

  • نام، تعریف‌شده توسط فیلد کنترل‌کننده.
  • مسیر سوار کردن، که با فیلد مسیر تعریف می‌شود.
  • حالت، UID (شناسه کاربر)، و GID (شناسه گروه) که مالک و حالت‌های دسترسی برای فایل‌های زیر این مسیر را توصیف می‌کند (همه اختیاری).
  • مشخصه اختیاری، روی true تنظیم کنید تا به سیستم اجازه دهید خطای نصب ناشی از کنترل‌کننده گروه کنترل را که هسته از نصب آن پشتیبانی نمی‌کند نادیده بگیرد.

فایل cgroups.json نمونه

مثال زیر شرح کنترل‌کننده‌های cgroup v1 (Cgroups) و cgroup v2 (Cgroups2) را با مسیرهای مربوطه نشان می‌دهد.

{
  "Cgroups": [
    {
      "Controller": "cpu",
      "Path": "/dev/cpuctl",
      "Mode": "0755",
      "UID": "system",
      "GID": "system"
    },
    {
      "Controller": "memory",
      "Path": "/dev/memcg",
      "Mode": "0700",
      "Optional": true
    }
  ],
 "Cgroups2": {
   "Path": "/sys/fs/cgroup",
   "Mode": "0755",
   "UID": "system",
   "GID": "system",
   "Controllers": [
     {
       "Controller": "freezer",
       "Path": ".",
       "Mode": "0755",
       "UID": "system",
       "GID": "system"
     }
   ]
 }
}

این فایل نمونه شامل دو بخش است، Cgroups (توضیح کنترل‌کننده‌های cgroup v1 ) و Cgroups2 (توضیح کنترل‌کننده‌های cgroup v2). همه کنترل‌کننده‌ها در سلسله‌مراتب cgroups v2 در مکان یکسانی نصب می‌شوند. بنابراین، بخش Cgroups2 دارای مشخصه‌های مسیر، حالت، UID، و GID خودش است تا مکان و مشخصه‌های ریشه سلسله‌مراتب را شرح دهد. مشخصه مسیر برای کنترل‌کننده‌ها در Cgroups2 نسبت‌به آن مسیر ریشه است. در Android 12 و بالاتر، می‌توانید کنترل‌کننده cgroup را که با مسیر و حالت به‌عنوان "Optional" مشخص شده است با تنظیم آن روی true تعریف کنید.

فایل cgroups.json به‌عنوان بخشی از فرایند init، در مرحله early-init تجزیه می‌شود و cgroupها در مکان‌های مشخص‌شده نصب می‌شوند. برای دریافت مکان‌های نصب cgroup در آینده، از تابع API CgroupGetControllerPath استفاده کنید.

فایل نمایه‌های تکلیف

فایل task_profiles.json در <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/ قرار دارد. از آن برای توصیف مجموعه خاصی از کنش‌ها که باید روی فرایند یا رشته اعمال شود استفاده کنید. مجموعه‌ای از کنش‌ها با نام نمایه مرتبط است که در SetTaskProfiles و SetProcessProfiles تماس‌ها برای فراخواندن کنش‌های نمایه استفاده می‌شود.

فایل نمونه task_profiles.json

{
  "Attributes": [
    {
      "Name": "MemSoftLimit",
      "Controller": "memory",
      "File": "memory.soft_limit_in_bytes"
    },
    {
      "Name": "MemSwappiness",
      "Controller": "memory",
      "File": "memory.swappiness"
    }
  ],
  "Profiles": [
    {
      "Name": "MaxPerformance",
      "Actions" : [
        {
          "Name" : "JoinCgroup",
          "Params" :
          {
            "Controller": "schedtune",
            "Path": "top-app"
          }
        }
      ]
    },
    {
      "Name": "TimerSlackHigh",
      "Actions" : [
        {
          "Name" : "SetTimerSlack",
          "Params" :
          {
            "Slack": "40000000"
          }
        }
      ]
    },
    {
      "Name": "LowMemoryUsage",
      "Actions" : [
        {
          "Name" : "SetAttribute",
          "Params" :
          {
            "Name" : "MemSoftLimit",
            "Value" : "16MB"
          }
        },
        {
          "Name" : "SetAttribute",
          "Params" :
          {
            "Name" : "MemSwappiness",
            "Value" : "150"

          }
        }
      ]
    }
  ]
  "AggregateProfiles": [
     {
       "Name": "SCHED_SP_DEFAULT",
       "Profiles": [ "TimerSlackHigh", "MaxPerformance" ]
     },
     {
       "Name": "SCHED_SP_BACKGROUND",
       "Profiles": [ "LowMemoryUsage" ]
     }
}

نام‌هایی را به فایل‌های cgroup خاص به‌عنوان ورودی در فهرست مشخصه‌ها اختصاص دهید. هر ورودی شامل موارد زیر است:

  • فیلد نام نام «مشخصه» را مشخص می‌کند.
  • فیلد کنترل‌کننده به کنترل‌کننده cgroup از فایل cgroups.json با نام آن ارجاع می‌دهد.
  • فیلد فایل نام فایل خاصی را تحت این کنترل‌کننده مشخص می‌کند.

مشخصه‌ها ارجاعاتی در تعاریف نمایه تکلیف هستند. خارج از نمایه‌های تکلیف، فقط زمانی از آن‌ها استفاده کنید که چارچوب به دسترسی مستقیم به آن فایل‌ها نیاز داشته باشد و دسترسی نتواند بااستفاده از نمایه‌های تکلیف انتزاعی شود. در همه موارد دیگر، از نمایه‌های وظیفه استفاده کنید؛ این نمایه‌ها جداسازی بهتری بین رفتار موردنیاز و جزئیات پیاده‌سازی آن ارائه می‌دهند.

بخش نمایه‌ها حاوی تعاریف نمایه تکلیف با موارد زیر است:

  • فیلد نام نام نمایه را تعریف می‌کند.
  • بخش کنش‌ها مجموعه‌ای از کنش‌های انجام‌شده هنگام اعمال نمایه را فهرست می‌کند. هر کنش دارای موارد زیر است:

    • فیلد نام کنش را مشخص می‌کند.
    • بخش Params مجموعه‌ای از پارامترها را برای کنش مشخص می‌کند.

کنش‌های پشتیبانی‌شده در جدول فهرست شده است:

کنش پارامتر شرح
SetTimerSlack Slack زمان‌سنج slack در ns
SetAttribute Name نامی که به مشخصه‌ای از بخش مشخصه‌ها ارجاع می‌دهد
Value مقداری که باید در فایل نشان‌داده‌شده با مشخصه نام‌گذاری‌شده نوشته شود
WriteFileFilePathمسیر فایل
Valueمقداری که در فایل نوشته می‌شود
JoinCgroup Controller نام کنترل‌کننده cgroup از cgroups.json
Path مسیر زیرگروه در سلسله‌مراتب کنترل‌کننده cgroup

‫Android 12 و نسخه‌های بالاتر دارای بخش AggregateProfiles است که حاوی نمایه‌های تجمیعی است و هریک از آن‌ها نام مستعار مجموعه‌ای از یک یا چند نمایه است. تعاریف نمایه تجمیعی شامل موارد زیر است:

  • فیلد نام نام نمایه تجمیعی را مشخص می‌کند.
  • فیلد نمایه‌ها نام نمایه‌های موجود در نمایه تجمعی را فهرست می‌کند.

وقتی نمایه تجمیعی اعمال می‌شود، همه نمایه‌های حاوی آن نیز به‌طور خودکار اعمال می‌شوند. نمایه‌های انبوهشی می‌توانند هم شامل نمایه‌های فردی باشند و هم نمایه‌های انبوهشی دیگر، به‌شرطی که بازگشتی وجود نداشته باشد (نمایه‌ای که خودش را شامل شود).

task_profiles init language command

فرمان task_profiles در زبان Android Init برای Android نسخه ۱۲ و بالاتر دردسترس است تا فعال‌سازی نمایه تکلیف را برای فرایندی خاص تسهیل کند. این فرمان جایگزین فرمان writepid (منسوخ‌شده در Android 12) می‌شود که برای انتقال فرایند بین cgroupها استفاده می‌شد. دستور task_profiles انعطاف‌پذیری لازم را برای تغییر پیاده‌سازی‌های زیرین بدون تأثیر بر لایه‌های بالایی فراهم می‌کند. در مثال زیر، این دو فرمان در عمل یک عملیات را انجام می‌دهند:

  • writepid /dev/cpuctl/top-app/tasks

    در Android 12 منسوخ شده است. از این برای نوشتن PID وظیفه فعلی در فایل /dev/cpuctl/top-app/tasks استفاده می‌شد.

  • task_profiles MaxPerformance

    فرایند فعلی را به گروه برنامه برتر در کنترل‌کننده «cpu» (cpuctl) اضافه می‌کند که منجر به نوشتن PID فرایند در dev/cpuctl/top-app/tasks می‌شود.

همیشه از فرمان task_profiles برای انتقال وظایف در سلسله‌مراتب گروه کنترل در Android 12 و بالاتر استفاده کنید. یک یا چند پارامتر را می‌پذیرد که نشان‌دهنده نام‌های نمایه‌های مشخص‌شده در فایل task_profiles.json است.

نمایه‌های تکلیف سطح میانای برنامه‌سازی کاربردی

در Android نسخه ۱۲ و بالاتر، می‌توانید تعاریف را در فایل‌های پیش‌فرض cgroups.json و task_profiles.json اصلاح یا لغو کنید، چه تغییراتتان را براساس سطح میانای برنامه‌سازی کاربردی Android انجام دهید یا آن را از پارتیشن فروشنده اعمال کنید.

برای ملغی کردن تعاریف براساس سطح API، فایل‌های زیر باید در دستگاه وجود داشته باشد:

  • /system/etc/task_profiles/cgroups_<API level>.json

    از این فرمان برای cgroups مختص سطح API استفاده کنید.

  • /system/etc/task_profiles/task_profiles_<API level>.json

    از این برای نمایه‌های مختص سطح میانای برنامه‌سازی کاربردی استفاده کنید.

برای ملغی کردن تعریف‌های پارتیشن فروشنده، فایل‌های زیر باید در دستگاه وجود داشته باشد:

  • /vendor/etc/cgroups.json
  • /vendor/etc/task_profiles.json

اگر یک مشخصه یا تعریف نمایه در این فایل‌ها از همان نامی استفاده کند که در فایل پیش‌فرض وجود دارد، تعریف فایل (سطح API یا سطح فروشنده) تعریف قبلی را ملغی می‌کند. همچنین توجه داشته باشید که تعریف‌های سطح فروشنده تعریف‌های سطح API را ملغی می‌کنند. اگر تعریف جدید نام جدیدی داشته باشد، مجموعه ویژگی‌ها یا نمایه‌ها با تعریف جدید اصلاح می‌شود.

سیستم Android فایل‌های cgroup و task_profile را به این ترتیب بار می‌کند:

  1. فایل‌های پیش‌فرض cgroups.json و task_profiles.json است.
  2. فایل‌های مختص سطح API، درصورت وجود.
  3. فایل‌های پارتیشن فروشنده، درصورت وجود.

تغییرات در میانای برنامه‌سازی کاربردی موجود

‫Android 10 و نسخه‌های بالاتر کارکردهای set_cpuset_policy، set_sched_policy، و get_sched_policy را بدون تغییر در «میانای برنامه‌سازی کاربردی» حفظ می‌کند. بااین‌حال، Android 10 این توابع را به libprocessgroup منتقل می‌کند، که اکنون حاوی همه عملکردهای مربوط به cgroup است.

اگرچه سرایند cutils/sched_policy.h همچنان وجود دارد، برای جلوگیری از خراب شدن کد موجود، مطمئن شوید که کد جدید به‌جای آن سرایند processgroup/sched_policy.h جدیدی را دربر می‌گیرد.

پیمانه‌هایی که از هرکدام از این توابع استفاده می‌کنند باید وابستگی به کتابخانه libprocessgroup را به فایل ساخت خود اضافه کنند. اگر واحدی از هیچ عملکرد دیگری libcutils استفاده نمی‌کند، libcutils وابستگی کتابخانه را از فایل ساخت حذف کنید.

میاناهای برنامه‌سازی کاربردی نمایه‌های تکلیف

میاناهای برنامه‌سازی کاربردی خصوصی در processgroup/processgroup.h در جدول زیر تعریف شده است:

نوع میانای برنامه‌سازی کاربردی و تعریف
bool SetTaskProfiles(int tid, const std::vector& profiles)
نمایه‌های تکلیف مشخص‌شده در profiles را به رشته مشخص‌شده با شناسه رشته (tid) بااستفاده از پارامتر tid آن اعمال می‌کند.
bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector& profiles)
نمایه‌های تکلیف مشخص‌شده در profiles را بااستفاده از پارامترهای uid و pid به فرایند مشخص‌شده توسط شناسه‌های کاربر و فرایند آن اعمال می‌کند
bool CgroupGetControllerPath(const std::string& cgroup_name, std::string* path)
بررسی می‌کند که آیا کنترل‌کننده cgroup مشخص‌شده توسط cgroup_name وجود دارد یا نه؛ اگر true، متغیر path را روی ریشه آن cgroup تنظیم می‌کند
bool CgroupGetAttributePath(const std::string& attr_name, std::string* path)
برمی‌گرداند که آیا مشخصه نمایه‌ای که attr_name مشخص کرده است وجود دارد یا نه؛ اگر true، متغیر path را روی مسیر فایل منسوب به آن مشخصه نمایه تنظیم می‌کند.
bool CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path)
برمی‌گرداند که آیا مشخصه نمایه‌ای که attr_name مشخص کرده است وجود دارد یا نه؛ اگر true، متغیر path را روی مسیر فایل منسوب به آن مشخصه نمایه و روی رشته مشخص‌شده با شناسه رشته آن بااستفاده از پارامتر tid تنظیم می‌کند.
bool UsePerAppMemcg()
برمی‌گرداند که آیا سیستم برای استفاده از گروه‌های کنترل حافظه هر برنامه پیکربندی شده است یا نه.