বাইন্ডার আইপিসি ব্যবহার করুন

এই পৃষ্ঠাটি Android 8-এ বাইন্ডার ড্রাইভারের পরিবর্তনগুলি বর্ণনা করে, বাইন্ডার আইপিসি ব্যবহার করার বিষয়ে বিশদ প্রদান করে এবং প্রয়োজনীয় SELinux নীতি তালিকাভুক্ত করে।

বাইন্ডার ড্রাইভার পরিবর্তন

Android 8 থেকে শুরু করে, Android ফ্রেমওয়ার্ক এবং HALs এখন বাইন্ডার ব্যবহার করে একে অপরের সাথে যোগাযোগ করে। যেহেতু এই যোগাযোগ নাটকীয়ভাবে বাইন্ডার ট্রাফিক বাড়ায়, তাই Android 8-এ বাইন্ডার আইপিসি দ্রুত রাখার জন্য ডিজাইন করা বেশ কিছু উন্নতি অন্তর্ভুক্ত রয়েছে। SoC বিক্রেতা এবং OEM-দের সরাসরি android-4.4, android-4.9, এবং কার্নেল/সাধারণ প্রকল্পের উচ্চতর প্রাসঙ্গিক শাখা থেকে একত্রিত হওয়া উচিত।

একাধিক বাইন্ডার ডোমেন (প্রসঙ্গ)

সাধারণ-4.4 এবং উচ্চতর, আপস্ট্রিম সহ

ফ্রেমওয়ার্ক (ডিভাইস-স্বাধীন) এবং বিক্রেতা (ডিভাইস-নির্দিষ্ট) কোডের মধ্যে বাইন্ডার ট্র্যাফিককে পরিষ্কারভাবে বিভক্ত করতে, অ্যান্ড্রয়েড 8 একটি বাইন্ডার প্রসঙ্গ ধারণাটি চালু করেছে। প্রতিটি বাইন্ডার প্রসঙ্গের নিজস্ব ডিভাইস নোড এবং নিজস্ব প্রসঙ্গ (পরিষেবা) ম্যানেজার রয়েছে। আপনি কনটেক্সট ম্যানেজারটি শুধুমাত্র ডিভাইস নোডের মাধ্যমে অ্যাক্সেস করতে পারেন যার সাথে এটি রয়েছে এবং একটি নির্দিষ্ট প্রেক্ষাপটের মাধ্যমে একটি বাইন্ডার নোড পাস করার সময়, এটি শুধুমাত্র একই প্রসঙ্গ থেকে অন্য একটি প্রক্রিয়ার মাধ্যমে অ্যাক্সেসযোগ্য, এইভাবে ডোমেনগুলিকে একে অপরের থেকে সম্পূর্ণ বিচ্ছিন্ন করে। ব্যবহারের বিস্তারিত জানার জন্য, vndbinder এবং vndservicemanager দেখুন।

বিচ্ছুরণ-জড়ো করা

সাধারণ-4.4 এবং উচ্চতর, আপস্ট্রিম সহ

অ্যান্ড্রয়েডের পূর্ববর্তী রিলিজে, একটি বাইন্ডার কলের প্রতিটি ডেটা তিনবার অনুলিপি করা হয়েছিল:

  • একবার কলিং প্রক্রিয়ায় এটিকে একটি Parcel সিরিয়ালাইজ করতে হবে
  • কার্নেল ড্রাইভারের মধ্যে একবার লক্ষ্য প্রক্রিয়ায় Parcel অনুলিপি করুন
  • লক্ষ্য প্রক্রিয়ায় Parcel একবার আনসিরিয়ালাইজ করা

অ্যান্ড্রয়েড 8 স্ক্যাটার-গেদার অপ্টিমাইজেশান ব্যবহার করে কপির সংখ্যা 3 থেকে 1 এ কমিয়ে আনে। Parcel ডেটা সিরিয়ালাইজ করার পরিবর্তে, ডেটা তার মূল গঠন এবং মেমরি লেআউটে থাকে এবং ড্রাইভার অবিলম্বে লক্ষ্য প্রক্রিয়ায় এটি কপি করে। ডেটা টার্গেট প্রক্রিয়ায় আসার পরে, গঠন এবং মেমরি লেআউট একই থাকে এবং ডেটা অন্য কপির প্রয়োজন ছাড়াই পড়া যায়।

সূক্ষ্ম দানাদার লকিং

সাধারণ-4.4 এবং উচ্চতর, আপস্ট্রিম সহ

পূর্ববর্তী অ্যান্ড্রয়েড রিলিজে, বাইন্ডার ড্রাইভার সমালোচনামূলক ডেটা স্ট্রাকচারে একযোগে অ্যাক্সেস থেকে রক্ষা করার জন্য একটি গ্লোবাল লক ব্যবহার করেছিল। যদিও লকটির জন্য ন্যূনতম বিরোধ ছিল, প্রধান সমস্যাটি ছিল যে যদি একটি কম-অগ্রাধিকার থ্রেড লকটি প্রাপ্ত করে এবং তারপরে প্রিমম্পড করা হয়, তবে এটি একই লকটি পাওয়ার জন্য প্রয়োজনীয় উচ্চ-অগ্রাধিকার থ্রেডগুলিকে গুরুতরভাবে বিলম্বিত করতে পারে। এর ফলে প্ল্যাটফর্মে জ্যাংক সৃষ্টি হয়।

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

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

রিয়েল-টাইম অগ্রাধিকার উত্তরাধিকার

কমন-4.4 এবং কমন-4.9 (আপস্ট্রিম শীঘ্রই আসছে)

বাইন্ডার ড্রাইভার সবসময় সুন্দর অগ্রাধিকার উত্তরাধিকার সমর্থন করেছে। অ্যান্ড্রয়েডে ক্রমবর্ধমান সংখ্যক প্রসেস রিয়েল-টাইম অগ্রাধিকারে চলার কারণে, কিছু ক্ষেত্রে এটি এখন বোঝা যায় যে যদি একটি রিয়েল-টাইম থ্রেড একটি বাইন্ডার কল করে, সেই প্রক্রিয়ার থ্রেডটি যে কলটি পরিচালনা করে তাও রিয়েল-টাইম অগ্রাধিকারে চলে . এই ব্যবহারের ক্ষেত্রে সমর্থন করার জন্য, Android 8 এখন বাইন্ডার ড্রাইভারে রিয়েল-টাইম অগ্রাধিকার উত্তরাধিকার প্রয়োগ করে।

লেনদেন-স্তরের অগ্রাধিকার উত্তরাধিকার ছাড়াও, নোড অগ্রাধিকার উত্তরাধিকার একটি নোডকে (বাইন্ডার পরিষেবা বস্তু) একটি ন্যূনতম অগ্রাধিকার নির্দিষ্ট করতে দেয় যেখানে এই নোডে কল করা উচিত। অ্যান্ড্রয়েডের পূর্ববর্তী সংস্করণগুলি ইতিমধ্যেই চমৎকার মান সহ নোড অগ্রাধিকার উত্তরাধিকার সমর্থিত, তবে অ্যান্ড্রয়েড 8 রিয়েল-টাইম শিডিউলিং নীতি নোড উত্তরাধিকারের জন্য সমর্থন যোগ করে।

ব্যবহারকারী স্থান পরিবর্তন

অ্যান্ড্রয়েড 8 একটি ব্যতিক্রম সহ সাধারণ কার্নেলে বর্তমান বাইন্ডার ড্রাইভারের সাথে কাজ করার জন্য প্রয়োজনীয় সমস্ত ব্যবহারকারীর স্থান পরিবর্তনগুলি অন্তর্ভুক্ত করে: /dev/binder এর জন্য রিয়েল-টাইম অগ্রাধিকার উত্তরাধিকার নিষ্ক্রিয় করার মূল বাস্তবায়ন একটি ioctl ব্যবহার করেছে। পরবর্তী উন্নয়ন অগ্রাধিকার উত্তরাধিকারের নিয়ন্ত্রণকে আরও সূক্ষ্ম পদ্ধতিতে পরিবর্তন করেছে যা প্রতি বাইন্ডার মোড (এবং প্রসঙ্গ অনুসারে নয়)। সুতরাং, ioctl অ্যান্ড্রয়েড সাধারণ শাখায় নেই এবং এর পরিবর্তে আমাদের সাধারণ কার্নেলে জমা দেওয়া হয়েছে।

এই পরিবর্তনের প্রভাব হল যে রিয়েল-টাইম অগ্রাধিকার উত্তরাধিকার ডিফল্টরূপে প্রতিটি নোডের জন্য অক্ষম করা হয়। অ্যান্ড্রয়েড পারফরম্যান্স টিম hwbinder ডোমেনের সমস্ত নোডের জন্য রিয়েল-টাইম অগ্রাধিকার উত্তরাধিকার সক্ষম করা উপকারী বলে মনে করেছে। একই প্রভাব অর্জন করতে, ব্যবহারকারীর জায়গায় এই পরিবর্তনটি চেরি-পিক করুন।

সাধারণ কার্নেলের জন্য SHA

বাইন্ডার ড্রাইভারে প্রয়োজনীয় পরিবর্তনগুলি পেতে, উপযুক্ত SHA-তে সিঙ্ক করুন:

  • কমন-3.18
    cc8b90c121de ANDROID: বাইন্ডার: পুনরুদ্ধারের জন্য প্রাইও অনুমতি পরীক্ষা করবেন না।
  • সাধারণ-4.4
    76b376eac7a2 ANDROID: বাইন্ডার: পুনরুদ্ধারের জন্য প্রাক অনুমতি পরীক্ষা করবেন না।
  • কমন-4.9
    ecd972d4f9b5 ANDROID: বাইন্ডার: পুনরুদ্ধারের জন্য প্রাইও অনুমতি পরীক্ষা করবেন না।

বাইন্ডার আইপিসি দিয়ে কাজ করুন

ঐতিহাসিকভাবে, বিক্রেতা প্রক্রিয়াগুলি যোগাযোগের জন্য বাইন্ডার ইন্টারপ্রসেস কমিউনিকেশন (IPC) ব্যবহার করেছে। অ্যান্ড্রয়েড 8-এ, /dev/binder ডিভাইস নোডটি ফ্রেমওয়ার্ক প্রক্রিয়াগুলির জন্য একচেটিয়া হয়ে ওঠে, যার অর্থ বিক্রেতা প্রক্রিয়াগুলির আর এটিতে অ্যাক্সেস নেই৷ বিক্রেতা প্রক্রিয়াগুলি /dev/hwbinder অ্যাক্সেস করতে পারে, কিন্তু HIDL ব্যবহার করার জন্য তাদের AIDL ইন্টারফেসকে রূপান্তর করতে হবে। যে সমস্ত বিক্রেতারা বিক্রেতা প্রক্রিয়াগুলির মধ্যে AIDL ইন্টারফেসগুলি ব্যবহার চালিয়ে যেতে চান তাদের জন্য, Android নীচে বর্ণিত হিসাবে বাইন্ডার IPC সমর্থন করে৷ অ্যান্ড্রয়েড 10-এ, স্থিতিশীল AIDL সমস্ত প্রক্রিয়াকে /dev/binder ব্যবহার করার অনুমতি দেয় এবং স্থিতিশীলতার গ্যারান্টি HIDL এবং /dev/hwbinder সমাধান করে। স্থিতিশীল এআইডিএল কীভাবে ব্যবহার করবেন তা জানতে, এইচএএল-এর জন্য এআইডিএল দেখুন।

vndbinder

অ্যান্ড্রয়েড 8 বিক্রেতা পরিষেবাগুলির দ্বারা ব্যবহারের জন্য একটি নতুন বাইন্ডার ডোমেন সমর্থন করে, /dev/binder এর পরিবর্তে /dev/vndbinder ব্যবহার করে অ্যাক্সেস করা হয়। /dev/vndbinder যোগ করার সাথে, Android-এ এখন নিম্নলিখিত তিনটি IPC ডোমেন রয়েছে:

IPC ডোমেইন বর্ণনা
/dev/binder AIDL ইন্টারফেস সহ ফ্রেমওয়ার্ক/অ্যাপ প্রক্রিয়াগুলির মধ্যে IPC
/dev/hwbinder HIDL ইন্টারফেস সহ ফ্রেমওয়ার্ক/বিক্রেতা প্রক্রিয়াগুলির মধ্যে IPC
HIDL ইন্টারফেস সহ বিক্রেতা প্রক্রিয়াগুলির মধ্যে IPC
/dev/vndbinder AIDL ইন্টারফেস সহ বিক্রেতা/বিক্রেতার প্রক্রিয়াগুলির মধ্যে IPC

/dev/vndbinder প্রদর্শিত হওয়ার জন্য, নিশ্চিত করুন যে কার্নেল কনফিগারেশন আইটেম CONFIG_ANDROID_BINDER_DEVICES সেট করা আছে "binder,hwbinder,vndbinder" (এটি অ্যান্ড্রয়েডের সাধারণ কার্নেল গাছগুলিতে ডিফল্ট)।

সাধারণত, বিক্রেতা প্রক্রিয়াগুলি বাইন্ডার ড্রাইভারকে সরাসরি খোলে না এবং পরিবর্তে libbinder ইউজারস্পেস লাইব্রেরির সাথে লিঙ্ক করে, যা বাইন্ডার ড্রাইভার খোলে। ::android::ProcessState() এর জন্য একটি পদ্ধতি যোগ করা libbinder জন্য বাইন্ডার ড্রাইভার নির্বাচন করে। ProcessState, IPCThreadState এ কল করার আগে বা সাধারণভাবে কোনো বাইন্ডার কল করার আগে ভেন্ডর প্রসেসগুলিকে এই পদ্ধতিতে কল করা উচিত। ব্যবহার করতে, একটি বিক্রেতা প্রক্রিয়া (ক্লায়েন্ট এবং সার্ভার) এর main() পরে নিম্নলিখিত কল করুন:

ProcessState::initWithDriver("/dev/vndbinder");

vndসার্ভিস ম্যানেজার

পূর্বে, বাইন্ডার পরিষেবাগুলি servicemanager এর সাথে নিবন্ধিত ছিল, যেখানে সেগুলি অন্যান্য প্রক্রিয়া দ্বারা পুনরুদ্ধার করা যেতে পারে। অ্যান্ড্রয়েড 8-এ, servicemanager এখন একচেটিয়াভাবে ফ্রেমওয়ার্ক এবং অ্যাপ প্রক্রিয়া দ্বারা ব্যবহৃত হয় এবং বিক্রেতা প্রক্রিয়াগুলি আর এটি অ্যাক্সেস করতে পারে না।

যাইহোক, বিক্রেতা পরিষেবাগুলি এখন vndservicemanager ব্যবহার করতে পারে, servicemanager এর একটি নতুন উদাহরণ যা /dev/ /dev/binder /dev/vndbinder ব্যবহার করে এবং যা ফ্রেমওয়ার্ক servicemanager এর মতো একই উৎস থেকে তৈরি করা হয়। vndservicemanager এর সাথে কথা বলার জন্য ভেন্ডর প্রসেস পরিবর্তন করতে হবে না; যখন একটি ভেন্ডর প্রসেস / dev/vndbinder খোলে, সার্ভিস লুকআপ স্বয়ংক্রিয়ভাবে vndservicemanager এ যায়।

vndservicemanager বাইনারি অ্যান্ড্রয়েডের ডিফল্ট ডিভাইস মেকফাইলে অন্তর্ভুক্ত করা হয়েছে।

SELinux নীতি

বিক্রেতা প্রক্রিয়াগুলি যেগুলি একে অপরের সাথে যোগাযোগ করতে বাইন্ডার কার্যকারিতা ব্যবহার করতে চায় তাদের নিম্নলিখিতগুলির প্রয়োজন:

  1. /dev/vndbinder এ অ্যাক্সেস।
  2. vndservicemanager এ বাইন্ডার {transfer, call} হুক।
  3. binder_call(A, B) যেকোন ভেন্ডর ডোমেইন A এর জন্য যা ভেন্ডর বাইন্ডার ইন্টারফেসের মাধ্যমে ভেন্ডর ডোমেইন B-এ কল করতে চায়।
  4. vndservicemanager{add, find} পরিষেবার অনুমতি।

প্রয়োজনীয়তা 1 এবং 2 পূরণ করতে, vndbinder_use() ম্যাক্রো ব্যবহার করুন:

vndbinder_use(some_vendor_process_domain);

প্রয়োজনীয়তা 3 পূরণ করতে, বিক্রেতা প্রক্রিয়া A এবং B এর জন্য binder_call(A, B) যা বাইন্ডারের উপর কথা বলার প্রয়োজন সে জায়গায় থাকতে পারে এবং এর নাম পরিবর্তনের প্রয়োজন নেই।

প্রয়োজনীয়তা 4 পূরণ করতে, আপনাকে অবশ্যই পরিষেবার নাম, পরিষেবা লেবেল এবং নিয়মগুলি পরিচালনা করার পদ্ধতিতে পরিবর্তন করতে হবে৷

SELinux-এর বিস্তারিত জানার জন্য, Android-এ নিরাপত্তা-বর্ধিত লিনাক্স দেখুন। Android 8.0-এ SELinux-এর বিস্তারিত জানার জন্য, Android 8.0-এর জন্য SELinux দেখুন।

পরিষেবার নাম

পূর্বে, বিক্রেতা একটি service_contexts ফাইলে নিবন্ধিত পরিষেবার নামগুলি প্রক্রিয়া করে এবং সেই ফাইলটি অ্যাক্সেস করার জন্য সংশ্লিষ্ট নিয়মগুলি যোগ করে। device/google/marlin/sepolicy থেকে service_contexts ফাইলের উদাহরণ:

AtCmdFwd                              u:object_r:atfwd_service:s0
cneservice                            u:object_r:cne_service:s0
qti.ims.connectionmanagerservice      u:object_r:imscm_service:s0
rcs                                   u:object_r:radio_service:s0
uce                                   u:object_r:uce_service:s0
vendor.qcom.PeripheralManager         u:object_r:per_mgr_service:s0

Android 8-এ, vndservicemanager পরিবর্তে vndservice_contexts ফাইল লোড করে। vndservicemanager এ স্থানান্তরিত বিক্রেতা পরিষেবাগুলি (এবং যা ইতিমধ্যেই পুরানো service_contexts ফাইলে রয়েছে) নতুন vndservice_contexts ফাইলে যোগ করা উচিত।

পরিষেবা লেবেল

পূর্বে, সার্ভিস লেবেল যেমন u:object_r:atfwd_service:s0 একটি service.te ফাইলে সংজ্ঞায়িত করা হয়েছিল। উদাহরণ:

type atfwd_service,      service_manager_type;

Android 8-এ, আপনাকে vndservice_manager_type এ টাইপ পরিবর্তন করতে হবে এবং নিয়মটিকে vndservice.te ফাইলে সরাতে হবে। উদাহরণ:

type atfwd_service,      vndservice_manager_type;

সার্ভিস ম্যানেজার নিয়ম

পূর্বে, নিয়মাবলী ডোমেইনগুলিকে servicemanager থেকে পরিষেবাগুলি যোগ করতে বা খুঁজে পেতে অ্যাক্সেস প্রদান করেছিল৷ উদাহরণ:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;

অ্যান্ড্রয়েড 8 এ, এই ধরনের নিয়মগুলি জায়গায় থাকতে পারে এবং একই ক্লাস ব্যবহার করতে পারে। উদাহরণ:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;