Cgroup অ্যাবস্ট্রাকশন লেয়ার

Android 10 ও তার পরবর্তী যেকোনও ভার্সনে টাস্ক প্রোফাইলের সাথে কন্ট্রোল গ্রুপ (cgroup) অ্যাবস্ট্রাকশন লেয়ার ব্যবহার করা হয়, যা ডেভেলপাররা থ্রেড বা প্রসেসে প্রয়োগ করার জন্য বিধিনিষেধের একটি সেট (বা একাধিক সেট) বর্ণনা করতে ব্যবহার করতে পারেন। তারপরে সিস্টেম এক বা একাধিক উপযুক্ত cgroup বেছে নিতে টাস্ক প্রোফাইলের নির্ধারিত অ্যাকশন অনুসরণ করে, যার মাধ্যমে বিধিনিষেধ প্রয়োগ করা হয় এবং আন্ডারলায়িং cgroup ফিচার সেটে পরিবর্তন করা যায়, এর ফলে উচ্চতর সফটওয়্যার লেয়ার প্রভাবিত হয় না।

cgroups সম্পর্কে

Cgroups, টাস্কের সেটকে (যার মধ্যে প্রসেস, থ্রেড ও তাদের ভবিষ্যৎ চাইল্ড প্রসেস পড়ে) বিশেষ আচরণ সহ হায়ারার্কিক্যাল গ্রুপে এগ্রিগেট ও পার্টিশন করার একটি মেকানিজম প্রদান করে। CPU ও মেমরি ব্যবহার ও অ্যালোকেশনের মতো সিস্টেম রিসোর্স কন্ট্রোল ও অ্যাকাউন্টের জন্য Android cgroups ব্যবহার করে। এটি Linux kernel cgroups v1 ও cgroups v2-এর সাথে কাজ করে।

Android 9 ও তার আগের যেকোনও ভার্সন

Android 9 ও তার আগের যেকোনও ভার্সনে, init.rc ইনিশিয়ালাইজেশন স্ক্রিপ্টে উপলভ্য cgroup, তাদের মাউন্টিং পয়েন্ট ও ভার্সনের সেট থাকে। এগুলি পরিবর্তন করা গেলেও, Android ফ্রেমওয়ার্ক আশা করে যে স্ক্রিপ্টের উপর ভিত্তি করে নির্দিষ্ট লোকেশনে নির্দিষ্ট ভার্সন ও সাবগ্রুপের ক্রম অনুযায়ী নির্দিষ্ট cgroups-এর সেট থাকবে। এর ফলে, ব্যবহার করার জন্য পরবর্তী cgroup ভার্সন বেছে নেওয়ার ক্ষমতা সীমিত হয়ে যায় অথবা নতুন ফিচার ব্যবহার করার জন্য cgroup হায়ারার্কি পরিবর্তন করা যায় না।

Android 10 ও তার পরবর্তী যেকোনও ভার্সন

Android 10 ও তার পরের যেকোনও ভার্সনে টাস্ক প্রোফাইলের সাথে cgroups ব্যবহার করা হয়:

  • Cgroup সেট-আপ। ডেভেলপাররা তাদের cgroups.json ফাইলে cgroup-এর সেট, তাদের মাউন্ট করার লোকেশন ও অ্যাট্রিবিউট নির্ধারণ করার জন্য cgroup সেট-আপ বর্ণনা করেন। ইনিশিয়ালাইজেশন প্রসেসের প্রাথমিক-ইনিট পর্যায়ে সব cgroup মাউন্ট করা হয়।
  • টাস্ক প্রোফাইল। এগুলি এমন একটি অ্যাবস্ট্রাকশন প্রদান করে যা প্রয়োজনীয় কার্যকারিতাকে এর প্রয়োগের বিবরণ থেকে আলাদা করে। Android ফ্রেমওয়ার্ক task_profiles.json ফাইলে বর্ণিত টাস্ক প্রোফাইলকে SetTaskProfiles এবং SetProcessProfiles API ব্যবহার করে প্রসেস বা থ্রেডে প্রয়োগ করে। (এইসব API Android 11 ও তার পরবর্তী যেকোনও ভার্সনের জন্য অনন্য।)

পুরনো ভার্সনের সাথে মানানসই করে তুলতে, পুরনো ফাংশন set_cpuset_policy, set_sched_policy এবং get_sched_policy একই API ও কার্যকারিতা প্রদান করে, কিন্তু টাস্ক প্রোফাইল ব্যবহার করার জন্য এগুলির প্রয়োগ পদ্ধতি পরিবর্তন করা হয়েছে। নতুন ব্যবহারের ক্ষেত্রে, AOSP পুরনো set_sched_policy ফাংশনের পরিবর্তে নতুন টাস্ক প্রোফাইল API ব্যবহার করার সাজেশন দেয়।

Cgroups বিবরণ ফাইল

Cgroups-এর বিবরণ <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/-এর মধ্যে থাকা cgroups.json ফাইলে দেওয়া আছে। প্রতিটি কন্ট্রোলারকে একটি করে উপবিভাগে বর্ণনা করা হয়েছে এবং সেগুলিতে অবশ্যই নিম্নলিখিত বিষয়গুলি থাকতে হবে:

  • কন্ট্রোলার ফিল্ডে সংজ্ঞায়িত নাম।
  • পাথ ফিল্ডের মাধ্যমে মাউন্ট করার পাথ নির্দিষ্ট করা হয়।
  • এই পাথের অধীনে থাকা ফাইলের মালিক ও অ্যাক্সেস মোড বর্ণনা করার জন্য মোড, UID (ব্যবহারকারীর আইডি) এবং GID (গ্রুপ আইডি) (সবকটিই ঐচ্ছিক)।
  • ঐচ্ছিক অ্যাট্রিবিউট, 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 (cgroup v1 কন্ট্রোলার বর্ণনা করে) এবং Cgroups2 (cgroup v2 কন্ট্রোলার বর্ণনা করে)। cgroups v2 হায়ারার্কিতে থাকা সব কন্ট্রোলার একই লোকেশনে মাউন্ট করা হয়। তাই, Cgroups2 বিভাগে নিজস্ব Path, Mode, UID এবং GID অ্যাট্রিবিউট আছে যা হায়ারার্কির রুটের লোকেশন ও অ্যাট্রিবিউট বর্ণনা করে। Cgroups2-এর অধীনে Controllers-এর জন্য Path অ্যাট্রিবিউট সেই রুট পাথের সাথে সম্পর্কিত। Android 12 ও তার পরবর্তী যেকোনও ভার্সনে, আপনি পাথ ও মোড সহ নির্দিষ্ট করা একটি cgroup কন্ট্রোলারকে "Optional" true হিসেবে সেট করে ডিফাইন করতে পারবেন।

ইনিট প্রসেসের অংশ হিসেবে, আর্লি-ইনিট স্টেজ চলাকালীন cgroups.json ফাইল পার্স করা হয় এবং নির্দিষ্ট লোকেশনে 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 ফাইলে নাম অ্যাসাইন করুন। প্রতিটি এন্ট্রিতে নিম্নলিখিত তথ্য থাকে:

  • নাম ফিল্ডে অ্যাট্রিবিউটের নাম উল্লেখ করা থাকে।
  • কন্ট্রোলার ফিল্ড, cgroups.json ফাইল থেকে, তার নাম অনুসারে, একটি cgroup কন্ট্রোলারকে রেফার করে।
  • ফাইল ফিল্ড এই কন্ট্রোলারের অধীনে একটি নির্দিষ্ট ফাইলের নাম।

টাস্ক প্রোফাইলের সংজ্ঞায় অ্যাট্রিবিউট হল রেফারেন্স। টাস্ক প্রোফাইলের বাইরে, ফ্রেমওয়ার্কের সেইসব ফাইল সরাসরি অ্যাক্সেস করার প্রয়োজন হলে এবং টাস্ক প্রোফাইল ব্যবহার করে অ্যাক্সেস অ্যাবস্ট্রাক্ট করা না গেলে, শুধুমাত্র তখনই সেগুলি ব্যবহার করুন। অন্য সব ক্ষেত্রে, টাস্ক প্রোফাইল ব্যবহার করুন; এগুলি প্রয়োজনীয় আচরণ এবং এর প্রয়োগের বিবরণের মধ্যে আরও ভাল ডিকাপলিং প্রদান করে।

প্রোফাইল বিভাগে নিম্নলিখিত বিষয় সহ টাস্ক প্রোফাইলের সংজ্ঞা থাকে:

  • নাম ফিল্ড প্রোফাইলের নাম নির্ধারণ করে।
  • অ্যাকশন বিভাগে প্রোফাইল প্রয়োগ করার সময় করা অ্যাকশনের সেট তালিকাভুক্ত করা থাকে। প্রতিটি অ্যাকশনে নিম্নলিখিত বিষয়গুলি থাকে:

    • নাম ফিল্ড অ্যাকশন নির্দিষ্ট করে।
    • Params বিভাগ অ্যাকশনের জন্য প্যারামিটারের একটি সেট নির্দিষ্ট করে।

টেবিলে কাজ করে এমন অ্যাকশন তালিকাভুক্ত করা আছে:

অ্যাকশন প্যারামিটার বর্ণনা
SetTimerSlack Slack টাইমারের স্ল্যাক, ন্যানোসেকেন্ডে
SetAttribute Name অ্যাট্রিবিউট বিভাগ থেকে কোনও অ্যাট্রিবিউটকে রেফারেন্স করা নাম
Value নামযুক্ত অ্যাট্রিবিউট দ্বারা উপস্থাপিত ফাইলে লেখার জন্য একটি মান
WriteFileFilePathফাইলের পাথ
Valueফাইলে লেখার জন্য একটি ভ্যালু
JoinCgroup Controller cgroups.json থেকে cgroup কন্ট্রোলারের নাম
Path cgroup কন্ট্রোলারের হায়ারার্কিতে একটি সাব-গ্রুপ পাথ

Android 12 ও তার পরের যেকোনও ভার্সনে AggregateProfiles বিভাগ থাকে যাতে এগ্রিগেট প্রোফাইল থাকে। এগুলির প্রত্যেকটি হল এক বা একাধিক প্রোফাইলের সেটের ছদ্মনাম। সামগ্রিক প্রোফাইল ডেফিনিশনে নিম্নলিখিত বিষয়গুলি থাকে:

  • নাম ফিল্ডে অ্যাগ্রিগেট প্রোফাইলের নাম উল্লেখ করা থাকে।
  • প্রোফাইল ফিল্ডে অ্যাগ্রিগেট প্রোফাইলে অন্তর্ভুক্ত প্রোফাইলের নাম তালিকাভুক্ত করা হয়।

কোনও অ্যাগ্রিগেট প্রোফাইল প্রয়োগ করা হলে, তার মধ্যে থাকা সব প্রোফাইলও অটোমেটিক প্রয়োগ করা হয়। এগ্রিগেট প্রোফাইলে ব্যক্তিগত প্রোফাইল বা অন্যান্য এগ্রিগেট প্রোফাইল থাকতে পারে, তবে কোনও রিকার্সন (এমন প্রোফাইল যা নিজেকে অন্তর্ভুক্ত করে) থাকলে চলবে না।

task_profiles init language কমান্ড

Android Init Language-এ task_profiles কমান্ড Android 12 ও এর পরের যেকোনও ভার্সনে উপলভ্য। এটি নির্দিষ্ট প্রসেসের জন্য টাস্ক প্রোফাইল অ্যাক্টিভেট করার সুবিধা দেয়। এটি writepid কমান্ডের (Android 12-এ বন্ধ করা হয়েছে) পরিবর্তে ব্যবহার করা হয় যা cgroup-এর মধ্যে প্রসেস মাইগ্রেট করতে ব্যবহার করা হত। task_profiles কমান্ডটি উপরের লেয়ারে কোনও প্রভাব না ফেলে আন্ডারলায়িং প্রয়োগ পরিবর্তন করার ক্ষেত্রে নমনীয়তা প্রদান করে। নিচের উদাহরণে, এই দুটি কমান্ড কার্যকরভাবে একই অপারেশন করে:

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

    Android 12-এ বন্ধ করে দেওয়া হয়েছে, এটি /dev/cpuctl/top-app/tasks ফাইলে বর্তমান টাস্কের PID লেখার জন্য ব্যবহার করা হত।

  • task_profiles MaxPerformance

    "cpu" কন্ট্রোলারের (cpuctl) অধীনে বর্তমান প্রসেসকে টপ-অ্যাপ গ্রুপে যোগ করে, যার ফলে প্রসেসের PID dev/cpuctl/top-app/tasks-এ লেখা হয়।

Android 12 ও তার পরবর্তী যেকোনও ভার্সনে cgroup হায়ারার্কিতে টাস্ক মাইগ্রেট করতে সবসময় task_profiles কমান্ড ব্যবহার করুন। এটি এক বা একাধিক প্যারামিটার গ্রহণ করে, যা task_profiles.json ফাইলে নির্দিষ্ট করা প্রোফাইলের নামের প্রতিনিধিত্ব করে।

প্রতি API-লেভেল টাস্ক প্রোফাইল

Android 12 ও তার পরবর্তী যেকোনও ভার্সনে, আপনি ডিফল্ট cgroups.json ও task_profiles.json ফাইলে সংজ্ঞা সংশোধন বা ওভাররাইড করতে পারবেন। এটি আপনি Android API লেভেলের উপর ভিত্তি করে অথবা ভেন্ডর পার্টিশন থেকে করতে পারবেন।

API লেভেলের উপর ভিত্তি করে সংজ্ঞা ওভাররাইড করতে, নিম্নলিখিত ফাইলগুলি ডিভাইসে থাকতে হবে:

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

    API লেভেলের জন্য নির্দিষ্ট cgroup-এর ক্ষেত্রে এটি ব্যবহার করুন।

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

    API লেভেলের জন্য নির্দিষ্ট প্রোফাইলে এটি ব্যবহার করুন।

ভেন্ডর পার্টিশন থেকে সংজ্ঞা ওভাররাইড করতে, ডিভাইসে নিম্নলিখিত ফাইলগুলি থাকতেই হবে:

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

এইসব ফাইলে কোনও অ্যাট্রিবিউট বা প্রোফাইল ডেফিনিশন যদি ডিফল্ট ফাইলের মতো একই নাম ব্যবহার করে, তাহলে ফাইল (API-লেভেল বা ভেন্ডর-লেভেল) ডেফিনিশন আগের ডেফিনিশনকে ওভাররাইড করে। এছাড়াও, মনে রাখবেন যে ভেন্ডর-লেভেল সংজ্ঞা API-লেভেল সংজ্ঞা পরিবর্তন করে দেয়। নতুন সংজ্ঞার নতুন নাম থাকলে, অ্যাট্রিবিউট বা প্রোফাইলের সেট নতুন সংজ্ঞা দিয়ে সংশোধন করা হয়।

Android সিস্টেম cgroup এবং task_profile ফাইলগুলি এই ক্রমে লোড করে:

  1. ডিফল্ট cgroups.json ও task_profiles.json ফাইল।
  2. API লেভেল-নির্দিষ্ট ফাইল, যদি থাকে।
  3. ভেন্ডর পার্টিশন ফাইল, যদি থাকে।

আগে থেকে থাকা API-তে পরিবর্তন

Android 10 ও তার পরবর্তী ভার্সনে API-তে কোনও পরিবর্তন না করেই set_cpuset_policy, set_sched_policy ও get_sched_policy ফাংশন কাজ করে। তবে, Android 10 এই ফাংশনগুলিকে libprocessgroup-এ সরিয়ে দেয়, যার মধ্যে এখন cgroup-সম্পর্কিত সমস্ত কার্যকারিতা রয়েছে।

যদিও cutils/sched_policy.h হেডার এখনও আছে, তবে আগে থেকে থাকা কোড যাতে ভেঙে না যায় তা নিশ্চিত করতে, নতুন কোডে যেন নতুন processgroup/sched_policy.h হেডার থাকে তা নিশ্চিত করুন।

এইসব ফাংশনের যেকোনও একটি ব্যবহার করে এমন মডিউলকে, সেটির মেকফাইলে libprocessgroup লাইব্রেরির উপর নির্ভরতা যোগ করতে হবে। কোনও মডিউল অন্য কোনও libcutils ফাংশনালিটি ব্যবহার না করলে, মেকফাইল থেকে libcutils লাইব্রেরি ডিপেন্ডেন্সি সরিয়ে দিন।

টাস্ক প্রোফাইল API

processgroup/processgroup.h-এর প্রাইভেট API সারণীতে সংজ্ঞায়িত করা হয়েছে:

ধরন API ও সংজ্ঞা
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_name দ্বারা নির্দিষ্ট করা cgroup কন্ট্রোলার আছে কিনা তা রিটার্ন করে; 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()
প্রতি-অ্যাপ মেমরি cgroups ব্যবহার করার জন্য সিস্টেম কনফিগার করা আছে কিনা তা রিটার্ন করে।