এই পৃষ্ঠায় Android 8-এ বাইন্ডার ড্রাইভারের পরিবর্তন সম্পর্কে বর্ণনা করা হয়েছে, বাইন্ডার IPC ব্যবহার করার বিষয়ে বিবরণ দেওয়া হয়েছে এবং প্রয়োজনীয় SELinux নীতির তালিকা দেওয়া হয়েছে।
বাইন্ডার ড্রাইভারের ক্ষেত্রে পরিবর্তন
Android 8 থেকে শুরু করে, Android ফ্রেমওয়ার্ক ও HAL এখন বাইন্ডার ব্যবহার করে একে অপরের সাথে যোগাযোগ করে। এই কমিউনিকেশন বাইন্ডার ট্রাফিককে নাটকীয়ভাবে বাড়িয়ে দেয়, তাই Android 8-এ বাইন্ডার IPC দ্রুত রাখার জন্য ডিজাইন করা বেশ কিছু উন্নতি অন্তর্ভুক্ত করা হয়েছে। SoC ভেন্ডর এবং OEM-এর উচিত android-4.4, android-4.9 এবং এর থেকে উন্নত ভার্সনের kernel/common প্রোজেক্টের প্রাসঙ্গিক ব্রাঞ্চ থেকে সরাসরি মার্জ করা।
একাধিক বাইন্ডার ডোমেন (প্রসঙ্গ)
আপস্ট্রিম সহ Common-4.4 এবং তার পরবর্তী ভার্সনফ্রেমওয়ার্ক (ডিভাইস-নিরপেক্ষ) এবং ভেন্ডর (ডিভাইস-নির্দিষ্ট) কোডের মধ্যে বাইন্ডার ট্রাফিককে পরিষ্কারভাবে ভাগ করার জন্য, Android 8-এ বাইন্ডার কনটেক্সট-এর ধারণা চালু করা হয়েছে। প্রতিটি বাইন্ডার কনটেক্সটের নিজস্ব ডিভাইস নোড ও নিজস্ব কনটেক্সট (পরিষেবা) ম্যানেজার থাকে। আপনি শুধুমাত্র সেই ডিভাইস নোডের মাধ্যমে কনটেক্সট ম্যানেজার অ্যাক্সেস করতে পারবেন যেটির সাথে এটি যুক্ত এবং কোনও নির্দিষ্ট কনটেক্সটের মাধ্যমে বাইন্ডার নোড পাস করার সময়, এটি শুধুমাত্র অন্য প্রসেসের মাধ্যমে একই কনটেক্সট থেকে অ্যাক্সেস করা যায়, এইভাবে ডোমেনগুলিকে একে অপরের থেকে সম্পূর্ণ আলাদা করা হয়। ব্যবহার করা সংক্রান্ত বিবরণের জন্য, vndbinder এবং vndservicemanager দেখুন।
স্ক্যাটার-গ্যাদার
আপস্ট্রিম সহ Common-4.4 এবং তার পরবর্তী ভার্সনAndroid-এর আগের রিলিজগুলিতে, বাইন্ডার কলের প্রতিটি ডেটা তিনবার কপি করা হত:
- কলিং প্রসেসে
Parcel-এ সিরিয়ালাইজ করার জন্য একবার Parcelথেকে টার্গেট প্রসেসে কপি করার জন্য কার্নেল ড্রাইভারের মধ্যে একবার- টার্গেট প্রসেসে
Parcel-কে আনসিরিয়ালাইজ করার জন্য একবার
Android 8-এ
স্ক্যাটার-গ্যাদার
অপ্টিমাইজেশন ব্যবহার করা হয় যাতে কপির সংখ্যা ৩ থেকে কমিয়ে ১ করা যায়। প্রথমে Parcel-এ ডেটা সিরিয়ালাইজ করার পরিবর্তে, ডেটা তার আসল স্ট্রাকচার ও মেমরি লেআউটে থাকে এবং ড্রাইভার অবিলম্বে এটিকে টার্গেট প্রসেসে কপি করে। টার্গেট প্রসেসে ডেটা চলে আসার পরে, স্ট্রাকচার ও মেমরি
লেআউট একই থাকে এবং অন্য কপি না করেই ডেটা পড়া যায়।
ফাইন-গ্রেনড লকিং
আপস্ট্রিম সহ Common-4.4 ও তার পরের যেকোনও ভার্সনআগের Android রিলিজগুলিতে, বাইন্ডার ড্রাইভার একটি গ্লোবাল লক ব্যবহার করত যাতে গুরুত্বপূর্ণ ডেটা স্ট্রাকচারে কনকারেন্ট অ্যাক্সেস থেকে রক্ষা করা যায়। লক নিয়ে খুব কমই বিরোধ দেখা গেলেও, মূল সমস্যা হল, কম অগ্রাধিকারের থ্রেড লক পেয়ে গেলে এবং তারপরে তা প্রিএম্পট করা হলে, একই লক পেতে চায় এমন বেশি অগ্রাধিকারের থ্রেড গুরুতরভাবে বিলম্বিত হতে পারে। এর ফলে প্ল্যাটফর্মে জ্যাঙ্ক দেখা দেয়।
এই সমস্যা সমাধানের প্রাথমিক প্রচেষ্টায় গ্লোবাল লক ধরে রাখার সময় প্রি-এমপশন বন্ধ করা অন্তর্ভুক্ত ছিল। তবে, এটি প্রকৃত সমাধান না হয়ে বরং একটি হ্যাক ছিল, এবং আপস্ট্রিম এটি বাতিল করে দেয়। পরবর্তী প্রচেষ্টা লকিংকে আরও সূক্ষ্ম-গ্রেনুলার করার উপর ফোকাস করে, যার একটি ভার্সন জানুয়ারি ২০১৭ থেকে Pixel ডিভাইসে চলছে। যদিও সেইসব পরিবর্তনের বেশিরভাগই সর্বজনীন করা হয়েছে, তবে পরবর্তী ভার্সনে উল্লেখযোগ্য উন্নতি করা হয়েছে।
ফাইন-গ্রেনড লকিং ইমপ্লিমেন্টেশনে ছোটখাটো সমস্যা শনাক্ত করার পরে, আমরা একটি উন্নত সমাধান তৈরি করেছি যাতে আলাদা লকিং আর্কিটেকচার ব্যবহার করা হয়েছে এবং সব সাধারণ কার্নেল ব্রাঞ্চে পরিবর্তনগুলি জমা দিয়েছি। আমরা বিভিন্ন ধরনের ডিভাইসে এই প্রয়োগ পরীক্ষা করে চলেছি; যেহেতু আমরা কোনও অমীমাংসিত সমস্যা সম্পর্কে অবগত নই, তাই Android 8-এর সাথে শিপিং করা ডিভাইসের জন্য এটিই প্রস্তাবিত প্রয়োগ।
রিয়েল-টাইম প্রায়োরিটি ইনহেরিটেন্স
Common-4.4 এবং common-4.9 (আপস্ট্রিম শীঘ্রই আসছে)বাইন্ডার ড্রাইভার সবসময়ই ভাল অগ্রাধিকার ইনহেরিটেন্সকে সমর্থন করে। Android-এ ক্রমবর্ধমান সংখ্যক প্রসেস রিয়েল-টাইম অগ্রাধিকারের ভিত্তিতে রান করে। কিছু ক্ষেত্রে, এখন এটি বোঝা যায় যে কোনও রিয়েল-টাইম থ্রেড বাইন্ডার কল করলে, সেই কল হ্যান্ডেল করা প্রসেসের থ্রেডও রিয়েল-টাইম অগ্রাধিকারের ভিত্তিতে রান করে। এইসব সম্ভাব্য পরিস্থিতিকে সাপোর্ট করতে, Android 8 এখন বাইন্ডার ড্রাইভারের মধ্যে রিয়েল-টাইম অগ্রাধিকার ইনহেরিটেন্স ইমপ্লিমেন্ট করে।
ট্রানজ্যাকশন-লেভেল প্রায়োরিটি ইনহেরিটেন্স ছাড়াও, নোড প্রায়োরিটি ইনহেরিটেন্স কোনও নোডকে (বাইন্ডার সার্ভিস অবজেক্ট) ন্যূনতম প্রায়োরিটি নির্দিষ্ট করতে দেয়, যে প্রায়োরিটিতে এই নোডে কল এক্সিকিউট করা উচিত। Android-এর আগের ভার্সনগুলিতে নাইস ভ্যালু সহ নোড প্রায়োরিটি ইনহেরিটেন্স আগে থেকেই কাজ করত, কিন্তু Android 8-এ রিয়েল-টাইম শিডিউলিং পলিসি নোড ইনহেরিটেন্সের জন্য সহায়তা যোগ করা হয়েছে।
ব্যবহারকারীর স্পেসে করা পরিবর্তন
Android 8-এ একটি ব্যতিক্রম সহ সাধারণ কার্নেলে বর্তমান
বাইন্ডার ড্রাইভারের সাথে কাজ করার জন্য প্রয়োজনীয় সমস্ত ইউজারস্পেস পরিবর্তন অন্তর্ভুক্ত রয়েছে: আসল
ইমপ্লিমেন্টেশন
/dev/binder-এর জন্য রিয়েল-টাইম অগ্রাধিকার ইনহেরিটেন্স বন্ধ করতে একটি
ioctl ব্যবহার করেছে। পরবর্তী ডেভেলপমেন্টে, প্রায়োরিটি
ইনহেরিটেন্সের কন্ট্রোলকে আরও ফাইন-গ্রেনড পদ্ধতিতে পরিবর্তন করা হয়েছে যা বাইন্ডার মোড (এবং
কনটেক্সট পিছু নয়) অনুযায়ী হয়। তাই, ioctl Android-এর সাধারণ ব্রাঞ্চে নেই এবং পরিবর্তে
আমাদের সাধারণ কার্নেলে জমা দেওয়া হয়েছে।
এই পরিবর্তনের ফলে, প্রতিটি নোডের জন্য ডিফল্ট হিসেবে রিয়েল-টাইম প্রায়োরিটি ইনহেরিটেন্স বন্ধ করা
হয়। Android পারফর্ম্যান্স টিম দেখেছে যে hwbinder ডোমেনের সব নোডের জন্য রিয়েল-টাইম প্রায়োরিটি ইনহেরিটেন্স চালু করলে
সুবিধা হয়। একই প্রভাব পেতে, userspace-এ
এই পরিবর্তন বেছে নিন।
সাধারণ কার্নেলের জন্য SHA
বাইন্ডার ড্রাইভারের প্রয়োজনীয় পরিবর্তন পেতে, উপযুক্ত SHA-তে সিঙ্ক করুন:
- Common-3.18
cc8b90c121de ANDROID: binder: don't check prio permissions on restore. - Common-4.4
76b376eac7a2 ANDROID: binder: don't check prio permissions on restore. - Common-4.9
ecd972d4f9b5 ANDROID: binder: don't check prio permissions on restore.
বাইন্ডার IPC-এর সাথে কাজ করা
ঐতিহাসিকভাবে, ভেন্ডর প্রসেস যোগাযোগের জন্য বাইন্ডার ইন্টারপ্রসেস কমিউনিকেশন
(IPC) ব্যবহার করেছে। Android 8-এ, /dev/binder ডিভাইস নোড
ফ্রেমওয়ার্ক প্রসেসের জন্য এক্সক্লুসিভ হয়ে যায়, যার অর্থ হল ভেন্ডর প্রসেসের কাছে আর
এটির অ্যাক্সেস থাকে না। ভেন্ডর প্রসেস /dev/hwbinder অ্যাক্সেস করতে পারে, কিন্তু
HIDL ব্যবহার করার জন্য তাদের AIDL ইন্টারফেস কনভার্ট করতে হবে। যেসব ভেন্ডর ভেন্ডর প্রসেসের মধ্যে AIDL ইন্টারফেস ব্যবহার করা চালিয়ে যেতে চান, তাদের জন্য Android নিচে
বর্ণিত বাইন্ডার IPC সাপোর্ট করে।
Android 10-এ, স্থিতিশীল AIDL সব
প্রসেসকে /dev/binder ব্যবহার করার অনুমতি দেয় এবং একই সাথে HIDL ও /dev/hwbinder-এর স্থিতিশীলতা
সংক্রান্ত গ্যারান্টি সংক্রান্ত সমস্যার সমাধান করে। কীভাবে Stable
AIDL ব্যবহার করতে হয় তা জানতে, HAL-এর জন্য AIDL দেখুন।
vndbinder
Android 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"-এ সেট করা আছে (এটি Android-এর
সাধারণ কার্নেল ট্রি-তে ডিফল্ট হিসেবে থাকে)।
সাধারণত, ভেন্ডর প্রসেস সরাসরি বাইন্ডার ড্রাইভার খোলে না এবং পরিবর্তে
libbinder ইউজারস্পেস লাইব্রেরির সাথে লিঙ্ক করে, যা
বাইন্ডার ড্রাইভার খোলে। ::android::ProcessState()
পদ্ধতি যোগ করলে libbinder-এর জন্য বাইন্ডার ড্রাইভার বেছে নেওয়া হয়। ভেন্ডর প্রসেসকে
ProcessState,
IPCThreadState-এ কল করার আগে অথবা সাধারণভাবে কোনও বাইন্ডার কল করার আগে এই পদ্ধতি কল করতে হবে। ব্যবহার
করতে, main()-এর পরে নিম্নলিখিত কলটি প্লেস করুন
কোনও ভেন্ডর প্রসেস (ক্লায়েন্ট ও সার্ভার):
ProcessState::initWithDriver("/dev/vndbinder");
vndservicemanager
আগে, বাইন্ডার পরিষেবা servicemanager-এর সাথে রেজিস্টার করা হত,
যেখানে অন্যান্য প্রসেসের মাধ্যমে সেগুলি ফিরিয়ে আনা যেত। Android 8-এ,
servicemanager এখন শুধুমাত্র ফ্রেমওয়ার্ক ও অ্যাপ প্রসেস ব্যবহার করে এবং
ভেন্ডর প্রসেস আর এটি অ্যাক্সেস করতে পারে না।
তবে, ভেন্ডর পরিষেবা এখন vndservicemanager ব্যবহার করতে পারে, এটি servicemanager-এর একটি নতুন
ইনস্ট্যান্স যা /dev/binder-এর পরিবর্তে /dev/vndbinder
ব্যবহার করে এবং যা ফ্রেমওয়ার্ক servicemanager-এর মতো একই সোর্স থেকে
তৈরি করা হয়। vndservicemanager-এর সাথে কথা বলার জন্য ভেন্ডর প্রসেসে
পরিবর্তন করার প্রয়োজন নেই; ভেন্ডর প্রসেস খুললে
/dev/vndbinder, পরিষেবা লুক-আপ অটোমেটিক
vndservicemanager-এ চলে যায়।
Android-এর ডিফল্ট
ডিভাইস মেকফাইলে vndservicemanager বাইনারি অন্তর্ভুক্ত থাকে।
SELinux নীতি
একে অপরের সাথে যোগাযোগ করার জন্য যেসব ভেন্ডর প্রসেস বাইন্ডার কার্যকারিতা ব্যবহার করতে চায়, তাদের নিম্নলিখিতগুলি প্রয়োজন:
/dev/vndbinder-এ অ্যাক্সেস।- বাইন্ডার
{transfer, call},vndservicemanager-এ হুক করে। binder_call(A, B)যেকোনও ভেন্ডর ডোমেন A-এর জন্য যা ভেন্ডর বাইন্ডার ইন্টারফেসের মাধ্যমে ভেন্ডর ডোমেন B-কে কল করতে চায়।vndservicemanager-এ{add, find}পরিষেবাতে অনুমতি।
১ ও ২ নম্বর প্রয়োজনীয়তা পূরণ করতে, vndbinder_use()
ম্যাক্রো ব্যবহার করুন:
vndbinder_use(some_vendor_process_domain);
৩ নম্বর প্রয়োজনীয়তা পূরণ করতে, ভেন্ডর
প্রসেস A ও B-এর জন্য binder_call(A, B) যা বাইন্ডারের মাধ্যমে কথা বলতে হবে তা নিজের জায়গায় থাকতে পারে এবং
নাম পরিবর্তন করার প্রয়োজন নেই।
৪ নম্বর প্রয়োজনীয়তা পূরণ করতে, পরিষেবা নাম, পরিষেবা লেবেল ও নিয়ম যেভাবে ম্যানেজ করা হয়, তাতে পরিবর্তন করতে হবে।
SELinux সম্পর্কে আরও জানতে, Android-এ নিরাপত্তা-উন্নত Linux দেখুন। 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 rules
আগে, নিয়মগুলি ডোমেনকে
servicemanager থেকে পরিষেবা যোগ করতে বা খুঁজতে অ্যাক্সেস দিত। উদাহরণ:
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;
Android 8-এ, এই ধরনের নিয়ম আগের মতোই থাকতে পারে এবং একই ক্লাস ব্যবহার করতে পারে। উদাহরণ:
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;