طبقة تجريد Cgroup

يستخدم الإصدار 10 من Android والإصدارات الأحدث مجموعة تحكّم (cgroup) لطبقة التجريد مع ملفات تعريف المهام، والتي يمكن للمطوّرين استخدامها لوصف مجموعة (أو مجموعات) من القيود لتطبيقها على سلسلة محادثات أو عملية. يتّبع النظام بعد ذلك الإجراءات المحدّدة لملفات تعريف المهام لاختيار مجموعة واحدة أو أكثر من مجموعات cgroup المناسبة التي يتم من خلالها تطبيق القيود، ويمكن إجراء تغييرات على مجموعة ميزات cgroup الأساسية بدون التأثير في مستويات البرامج الأعلى.

لمحة عن مجموعات cgroups

توفّر مجموعات Cgroups آلية لتجميع مجموعات المهام (التي تتألف من العمليات والخيوط وجميع العناصر الفرعية المستقبلية) وتقسيمها إلى مجموعات هرمية بسلوك متخصص. يستخدم نظام التشغيل Android مجموعات cgroups للتحكّم في موارد النظام، مثل استخدام وحدة المعالجة المركزية (CPU) والذاكرة وتخصيصها، مع إمكانية استخدام الإصدار 1 من مجموعات cgroups والإصدار 2 من مجموعات cgroups لنظام التشغيل Linux.

الإصدار 9 من Android والإصدارات الأقدم

في الإصدار 9 من Android والإصدارات الأقدم، كان نص إعداد init.rc يتضمّن مجموعة من مجموعات cgroup المتاحة ونقاط تركيبها وإصداراتها. على الرغم من أنّه يمكن تغيير هذه الإعدادات، كان إطار عمل Android يتوقّع توفُّر مجموعة معيّنة من مجموعات cgroups في مواقع معيّنة مع تسلسل هرمي محدّد للإصدار والمجموعة الفرعية، استنادًا إلى النص البرمجي. وقد أدّى ذلك إلى الحدّ من إمكانية اختيار إصدار cgroup التالي لاستخدامه أو تغيير التسلسل الهرمي cgroup لاستخدام الميزات الجديدة.

الإصدار 10 من نظام التشغيل Android والإصدارات الأحدث

يستخدم الإصدار 10 من Android والإصدارات الأحدث مجموعات cgroup مع ملفات تعريف المهام:

  • إعداد مجموعة Cgroup يصف المطوّرون إعداد مجموعات cgroups في cgroups.jsonملفهم لتحديد مجموعات مجموعات cgroups ومواقع تثبيتها وصفاتها. يتم تركيب جميع مجموعات cgroups خلال مرحلة الإعداد المبكر لعملية الإعداد.
  • ملفّات تعريف المهام: وتوفّر هذه الوحدات نموذجًا مجردًا يفصل بين الوظيفة المطلوبة وتفاصيل تنفيذها. يطبِّق إطار عمل Android ملفات تعريف المهام كما هو موضّح في ملف task_profiles.json على عملية أو سلسلة محادثات باستخدام واجهات برمجة التطبيقات SetTaskProfiles وSetProcessProfiles. (هذه الواجهات فريدة لنظام التشغيل Android 11 والإصدارات الأحدث).

لتوفير التوافق مع الإصدارات القديمة، توفّر الدوالّ القديمة set_cpuset_policy وset_sched_policy وget_sched_policy واجهة برمجة التطبيقات والوظائف نفسها، ولكن تم تعديل عملية تنفيذها لاستخدام الملفات الشخصية للمهام. بالنسبة إلى حالات الاستخدام الجديدة، ينصح فريق AOSP باستخدام واجهات برمجة التطبيقات الجديدة لملفات الأداء المهام بدلاً من الدالة set_sched_policy القديمة.

ملف وصف مجموعات Cgroups

يتم وصف مجموعات Cgroups في ملف cgroups.json المتوفّر ضمن <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/. يتم وصف كل وحدة تحكّم في قسم فرعي، ويجب أن تتضمّن الحد الأدنى مما يلي:

  • الاسم، الذي يحدّده الحقل جهاز التحكّم
  • مسار التثبيت، الذي يحدّده حقل المسار
  • الوضع وUID (معرّف المستخدم) وGID (معرّف المجموعة) لوصف المالك وmodi وضع الوصول إلى الملفات ضمن هذا المسار (كلها اختيارية)
  • سمة اختيارية، يتم ضبطها على true للسماح للنظام بتجاهل خطأ التثبيت الذي يتسبب فيه وحدة تحكّم في مجموعة cgroup لا يسمح لها بالتركيب.

مثال على ملف 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 (الذي يصف أدوات التحكّم في الإصدار 1 من cgroup) وCgroups2 (الذي يصف أدوات التحكّم في الإصدار 2 من cgroup). يتم تثبيت جميع عناصر التحكّم في التدرّج الهرمي لإصدار 2 من مجموعات cgroup في المكان نفسه. لذلك، يحتوي القسم Cgroups2 على سمات المسار والوضع وUID و GID لوصف الموقع الجغرافي وسمات جذر التسلسل الهرمي. تكون سمة المسار لـ وحدات التحكّم ضمن Cgroups2 نسبية إلى هذا المسار الجذر. في الإصدار 12 من Android والإصدارات الأحدث، يمكنك تحديد وحدة تحكّم في cgroup يتم تحديدها بالمسار والوضع على النحو التالي: "Optional" من خلال ضبطها على true.

يتم تحليل ملف cgroups.json كجزء من عملية init، أثناء مرحلة الإعداد المبكر ، ويتم تثبيت مجموعات cgroup في المواقع المحدّدة. للحصول لاحقًا على مواقع تثبيت cgroup، استخدِم دالة CgroupGetControllerPath API.

ملف الملفات الشخصية للمهام

يمكنك العثور على ملف 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 ، وذلك حسب اسمه.
  • يحدِّد حقل File اسم ملف معيّن ضمن وحدة التحكّم هذه.

السمات هي إحالات في تعريفات الملف الشخصي للمهمة. خارج ملفات ملفّات العميل ، استخدِم ملفات العميل فقط عندما يتطلّب إطار العمل الوصول المباشر إلى ملفات العميل هذه، ولا يمكن تجميع الوصول باستخدام ملفات العميل. في جميع الحالات الأخرى، استخدِم ملفات تعريف المهام، فهي توفّر فصلًا أفضل بين السلوك المطلوب و تفاصيل تنفيذه.

يحتوي قسم الملفات الشخصية على تعريفات ملفات تعريف المهام مع ما يلي:

  • يحدِّد حقل الاسم اسم الملف الشخصي.
  • يسرد قسم الإجراءات مجموعة من الإجراءات التي يتم تنفيذها عند تطبيق الملف التجاري. يحتوي كل إجراء على ما يلي:

    • يحدّد حقل الاسم الإجراء.
    • يحدِّد قسم المَعلمات مجموعة من المَعلمات للعمل.

يتم إدراج الإجراءات المتاحة في الجدول:

الإجراء المَعلمة الوصف
SetTimerSlack Slack وقت الاستراحة للموقّت بالنانومتر
SetAttribute Name اسم يشير إلى سمة من قسم السمات
Value قيمة ستتم كتابتها إلى الملف الذي تمثّله السمة المُسمّاة
WriteFileFilePathمسار الملف
Valueقيمة ليتم كتابتها في الملف
JoinCgroup Controller اسم وحدة تحكّم cgroup من cgroups.json
Path مسار مجموعة فرعية في التسلسل الهرمي لوحدة التحكّم في مجموعة التحكم (cgroup)

يتضمّن الإصدار 12 من Android والإصدارات الأحدث قسم AggregateProfiles الذي يحتوي على ملفات تجارية مجمّعة، وكل منها هو اسم بديل لمجموعة من ملف تجاري واحد أو أكثر. تتألف تعريفات الملفات التجارية المجمّعة من ما يلي:

  • يحدِّد حقل الاسم اسم الملف الشخصي المجمّع.
  • يسرد حقل الملفّات الشخصية أسماء الملفّات الشخصية المضمّنة فيملفّ الأداء المُجمّع.

عند تطبيق ملف شخصي مجمّع، يتم أيضًا تطبيق جميع الملفات الشخصية المضمّنة تلقائيًا. يمكن أن تحتوي الملفات الشخصية المجمّعة على كلّ من الملفات الشخصية الفردية أو الملفات الشخصية المجمّعة الأخرى، ما دامت لا تتضمّن تكرارات (ملف شخصي يتضمّن نفسه).

task_profiles init language command

يتوفّر الأمر task_profiles في لغة Android Init لنظام التشغيل Android 12 والإصدارات الأحدث لتسهيل تفعيل ملف تعريف المهام لعملية معيّنة. ويحلّ هذا الأمر محلّ الأمر writepid (الذي تم إيقافه نهائيًا في Android 12) الذي كان يُستخدَم لنقل عملية بين مجموعات cgroup. يقدّم الأمر task_profiles مرونة في تغيير عمليات التنفيذ الأساسية بدون التأثير في الطبقات العليا. في المثال التالي، يؤدي هذان الأمران العملية نفسها بفعالية:

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

    تم إيقاف هذا الإجراء نهائيًا في Android 12، وكان يُستخدَم لكتابة رقم تعريف العملية للمهمة الحالية في ملف /dev/cpuctl/top-app/tasks.

  • task_profiles MaxPerformance

    ينضمّ إلى العملية الحالية في مجموعة التطبيقات الرئيسية ضمن وحدة التحكّم في "وحدة المعالجة المركزية" (cpuctl)، ما يؤدي إلى كتابة معرّف PID للعملية في dev/cpuctl/top-app/tasks.

استخدِم دائمًا الأمر task_profiles لنقل المهام في التسلسلات الهرميّة لمجموعات cgroup في Android 12 والإصدارات الأحدث. يقبل هذا العمود مَعلمة واحدة أو أكثر تمثّل اسمَي الملفَين التجاريَّين المحدَّدَين في ملف task_profiles.json.

الملفات الشخصية للمهام على مستوى واجهة برمجة التطبيقات

في الإصدار 12 من Android والإصدارات الأحدث، يمكنك تعديل التعريفات في الملفَين التلقائيَين cgroups.json وtask_profiles.json أو إلغاء تطبيقها، إما بالاستناد إلى مستوى واجهة برمجة التطبيقات لنظام Android أو من قسم المورّد.

لإلغاء التعريفات استنادًا إلى مستوى واجهة برمجة التطبيقات، يجب أن تكون الملفات التالية متوفّرة على الجهاز:

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

    استخدِم هذا الخيار لمجموعات cgroup الخاصة بمستوى واجهة برمجة التطبيقات.

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

    استخدِم هذا الخيار للملفات التجارية الخاصة بمستوى واجهة برمجة التطبيقات.

لإلغاء التعريفات من قسم المورّد، يجب أن تكون الملفات التالية متوفّرة على الجهاز:

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

إذا كانت السمة أو تعريف الملف الشخصي في هذه الملفات يستخدمان الاسم نفسه الوارد في الملف التلقائي، تلغي تعريف الملف (على مستوى واجهة برمجة التطبيقات أو مستوى المورّد) التعريف السابق. يُرجى العلم أيضًا أنّ التعريفات على مستوى المورّد تلغي التعريفات على مستوى واجهة برمجة التطبيقات. إذا كان التعريف الجديد يحمل اسمًا جديدًا، يتم تعديل مجموعة السمات أو الملفات الشخصية باستخدام التعريف الجديد.

يحمِّل نظام Android ملفَي cgroup وtask_profile بالترتيب التالي:

  1. الملفات التلقائية بتنسيق cgroups.json وtask_profiles.json
  2. الملفات الخاصة بمستوى واجهة برمجة التطبيقات، إن توفّرت
  3. ملفات قسم المورِّد، إن توفّرت

التغييرات على واجهة برمجة التطبيقات الحالية

يحافظ نظام التشغيل Android 10 والإصدارات الأحدث على الدوالّ set_cpuset_policy set_sched_policy وget_sched_policy بدون تغييرات على واجهة برمجة التطبيقات. ومع ذلك، ينقل نظام التشغيل Android 10 هذه الدوال إلى libprocessgroup، الذي يحتوي الآن على جميع الوظائف ذات الصلة بمجموعة التحكم في العمليات.

على الرغم من أنّ العنوان cutils/sched_policy.h لا يزال متوفّرًا، لتجنّب تعطُّل الرمز الحالي، تأكَّد من أنّ الرمز الجديد يتضمّن عنوان processgroup/sched_policy.h جديدًا بدلاً من ذلك.

يجب أن تضيف الوحدات التي تستخدم أيًا من هذه الدوالّ تبعية لمكتبة libprocessgroup في ملف الإنشاء. إذا كانت إحدى الوحدات لا تستخدم أي وظائف libcutils أخرى، أزِل الاعتماد على مكتبة libcutils من ملف makefile.

واجهات برمجة التطبيقات للملفات التجارية

يتم تحديد واجهات برمجة التطبيقات الخاصة في 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 متوفّرة. إذا كانت قيمة attr_name هي true، يتم ضبط المتغيّر path على مسار الملف المرتبط بسمة الملف الشخصي هذه، وعلى سلسلة المحادثات المحدّدة من خلال معرّف سلسلة المحادثات باستخدام المَعلمة tid.
bool UsePerAppMemcg()
يعرض ما إذا كان النظام قد تم ضبطه لاستخدام مجموعات تحكم الذاكرة لكل تطبيق.