طبقة التجريد Cgroup

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

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

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

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

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

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

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

  • إعداد المجموعة الفرعية: يصف المطوّرون إعداد مجموعات cgroup في cgroups.jsonملف لتحديد مجموعات cgroup ومواقع تثبيتها وصفاتها. يتم تثبيت جميع مجموعات 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 من مجموعات الألعاب في مكان واحد. ولذلك، يحتوي القسم 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، وكان يُستخدَم لكتابة رقم تعريف العملية (PID) للمهمة الحالية في ملف /dev/cpuctl/top-app/tasks.

  • task_profiles MaxPerformance

    ينضمّ إلى العملية الحالية في مجموعة التطبيقات الرئيسية ضمن وحدة التحكّم "cpu" (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

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

  • /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، الذي يتضمّن الآن جميع الوظائف المتعلقة بمجموعات Google.

على الرغم من أنّ العنوان 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()
يعرض ما إذا كان النظام قد تم ضبطه لاستخدام مجموعات تحكم الذاكرة لكل تطبيق.