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

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

حول مجموعات التحكم

توفر مجموعات التحكم آلية لتجميع وتقسيم مجموعات المهام (التي تتكون من العمليات والخيوط وجميع أبنائها المستقبليين) إلى مجموعات هرمية ذات سلوك متخصص. يستخدم Android مجموعات cgroups للتحكم في موارد النظام وحسابها مثل وحدة المعالجة المركزية واستخدام الذاكرة وتخصيصها، مع دعم Linux kernel cgroups v1 و cgroups v2 .

أندرويد 9 وأقل

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

أندرويد 10 وما فوق

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

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

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

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

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

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

يتم تحليل ملف cgroups.json كجزء من عملية init، خلال مرحلة init المبكرة، ويتم تثبيت مجموعات cgroups في المواقع المحددة. للحصول على مواقع تركيب 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 ، حسب اسمه.
  • حقل الملف - يسمي ملفًا محددًا ضمن وحدة التحكم هذه.

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

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

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

    • حقل الاسم الذي يحدد الإجراء
    • قسم المعلمات يحدد مجموعة من المعلمات للإجراء

يتم سرد الإجراءات المدعومة في الجدول أدناه.

فعل معامل وصف
SetTimerSlack Slack الموقت الركود في ns
SetAttribute Name اسم يشير إلى سمة من قسم السمات
Value القيمة المراد كتابتها إلى الملف الذي تمثله السمة المسماة
WriteFile FilePath المسار إلى الملف
Value القيمة المراد كتابتها في الملف
JoinCgroup Controller اسم وحدة تحكم cgroup من cgroups.json
Path مسار مجموعة فرعية في التسلسل الهرمي لوحدة تحكم المجموعة

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

  • حقل الاسم - يحدد اسم ملف التعريف المجمع.
  • حقل ملفات التعريف - يسرد أسماء ملفات التعريف المضمنة في ملف التعريف المجمع.

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

مهمة Task_profiles init أمر اللغة

يتوفر أمر task_profiles بلغة Android Init لنظام Android 12 والإصدارات الأحدث لتسهيل تنشيط ملف تعريف المهمة لعملية معينة. فهو يحل محل أمر writepid (المهمل في Android 12) الذي تم استخدامه لترحيل العملية بين مجموعات التحكم. يوفر أمر 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 .

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

في نظام التشغيل Android 12 والإصدارات الأحدث، يمكنك تعديل التعريفات أو تجاوزها في ملفات cgroups.json و task_profiles.json الافتراضية، إما بناءً على تغييرك على مستوى Android API، أو إجراؤه من قسم البائع.

لتجاوز التعريفات المستندة إلى مستوى واجهة برمجة التطبيقات (API)، يجب أن تكون الملفات التالية موجودة على الجهاز:

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

    استخدم هذا لمجموعات cgroup الخاصة بمستوى API.

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

    استخدم هذا لملفات التعريف الخاصة بمستوى API.

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

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

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

يقوم نظام 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 من ملف makefile.

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

يتم تعريف واجهات برمجة التطبيقات الخاصة في processgroup/processgroup.h في الجدول أدناه:

يكتب واجهة برمجة التطبيقات والتعريف
bool SetTaskProfiles(int tid, const std::vector & profiles) SetTaskProfiles(int tid, const std::vector & profiles)

يطبق ملفات تعريف المهام المحددة في profiles على مؤشر الترابط المحدد بواسطة معرف مؤشر الترابط (tid) باستخدام معلمة tid الخاصة به.

bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector & profiles) 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()

إرجاع ما إذا كان النظام قد تم تكوينه لاستخدام مجموعات الذاكرة لكل تطبيق.