লেগ্যাসি এ/বি সিস্টেম আপডেট, যা সিমলেস আপডেট নামেও পরিচিত, ওভার-দ্য-এয়ার (OTA) আপডেটের সময় ডিস্কে একটি কার্যকর বুটিং সিস্টেম বজায় রাখা নিশ্চিত করে। এই পদ্ধতিটি আপডেটের পরে ডিভাইস নিষ্ক্রিয় হয়ে যাওয়ার সম্ভাবনা কমিয়ে দেয়, যার ফলে মেরামত এবং ওয়ারেন্টি কেন্দ্রগুলিতে ডিভাইস প্রতিস্থাপন এবং রিফ্ল্যাশের প্রয়োজন কমে যায়। ক্রোমওএস- এর মতো অন্যান্য বাণিজ্যিক মানের অপারেটিং সিস্টেমও সফলভাবে এ/বি আপডেট ব্যবহার করে।
এ/বি সিস্টেম আপডেট এবং এগুলি কীভাবে কাজ করে সে সম্পর্কে আরও তথ্যের জন্য, পার্টিশন নির্বাচন (স্লট) দেখুন।
এ/বি সিস্টেম আপডেট নিম্নলিখিত সুবিধাগুলো প্রদান করে:
- সিস্টেম চালু থাকা অবস্থাতেই OTA আপডেট সম্পন্ন হতে পারে, যা ব্যবহারকারীকে বাধা দেয় না। OTA চলাকালীন ব্যবহারকারীরা তাদের ডিভাইস ব্যবহার চালিয়ে যেতে পারেন—আপডেটের সময় একমাত্র ডাউনটাইম হলো যখন ডিভাইসটি আপডেট করা ডিস্ক পার্টিশনে রিবুট হয়।
- আপডেটের পরে রিবুট করতে সাধারণ রিবুটের চেয়ে বেশি সময় লাগে না।
- যদি কোনো OTA আপডেট প্রয়োগ করা না যায় (উদাহরণস্বরূপ, ফ্ল্যাশে কোনো ত্রুটির কারণে), তবে ব্যবহারকারী প্রভাবিত হবেন না। ব্যবহারকারী পুরোনো OS-টিই ব্যবহার করতে থাকবেন এবং ক্লায়েন্ট পুনরায় আপডেট করার চেষ্টা করতে পারবেন।
- যদি কোনো OTA আপডেট প্রয়োগ করার পর ডিভাইসটি বুট করতে ব্যর্থ হয়, তবে এটি পুরোনো পার্টিশনে রিবুট হয়ে যাবে এবং ব্যবহারযোগ্য থাকবে। ক্লায়েন্ট চাইলে পুনরায় আপডেটটি চেষ্টা করতে পারেন।
- যেকোনো ত্রুটি (যেমন I/O ত্রুটি) শুধুমাত্র অব্যবহৃত পার্টিশন সেটকে প্রভাবিত করে এবং পুনরায় চেষ্টা করা যেতে পারে। এই ধরনের ত্রুটির সম্ভাবনাও কমে যায়, কারণ ব্যবহারকারীর অভিজ্ঞতার অবনতি এড়ানোর জন্য I/O লোড ইচ্ছাকৃতভাবে কম রাখা হয়।
- আপডেটগুলো একাধিক ডিভাইসে স্ট্রিম করা যায়, ফলে ইনস্টল করার আগে প্যাকেজটি ডাউনলোড করার প্রয়োজন হয় না। স্ট্রিমিংয়ের অর্থ হলো, আপডেট প্যাকেজটি
/dataবা/cacheএ সংরক্ষণ করার জন্য ব্যবহারকারীর পর্যাপ্ত খালি জায়গা থাকার প্রয়োজন নেই। - OTA আপডেট প্যাকেজ সংরক্ষণের জন্য ক্যাশ পার্টিশন এখন আর ব্যবহৃত হয় না, তাই ভবিষ্যতের আপডেটের জন্য ক্যাশ পার্টিশন যথেষ্ট বড় কিনা তা নিশ্চিত করার কোনো প্রয়োজন নেই।
- ডিএম-ভেরিটি নিশ্চিত করে যে একটি ডিভাইস একটি ত্রুটিমুক্ত ইমেজ দিয়ে বুট করবে। যদি কোনো ত্রুটিপূর্ণ OTA বা ডিএম-ভেরিটি সমস্যার কারণে ডিভাইসটি বুট না হয়, তবে ডিভাইসটি একটি পুরোনো ইমেজে রিবুট করতে পারে। (অ্যান্ড্রয়েড ভেরিফায়েড বুটের জন্য A/B আপডেটের প্রয়োজন হয় না।)
এ/বি সিস্টেম আপডেট সম্পর্কে
A/B আপডেটের জন্য ক্লায়েন্ট এবং সিস্টেম উভয় ক্ষেত্রেই পরিবর্তন প্রয়োজন। তবে, OTA প্যাকেজ সার্ভারে কোনো পরিবর্তনের প্রয়োজন নেই: আপডেট প্যাকেজগুলো এখনও HTTPS-এর মাধ্যমেই সরবরাহ করা হয়। যেসব ডিভাইস গুগলের OTA পরিকাঠামো ব্যবহার করে, সেগুলোর ক্ষেত্রে সিস্টেমের সমস্ত পরিবর্তন AOSP-তে করা হয় এবং ক্লায়েন্ট কোড গুগল প্লে সার্ভিসেস সরবরাহ করে থাকে। যেসব OEM গুগলের OTA পরিকাঠামো ব্যবহার করে না, তারা AOSP সিস্টেম কোডটি পুনরায় ব্যবহার করতে পারবে, কিন্তু তাদের নিজস্ব ক্লায়েন্ট সরবরাহ করতে হবে।
যেসব OEM তাদের নিজস্ব গ্রাহককে পণ্য সরবরাহ করে, সেই গ্রাহকের নিম্নলিখিত বিষয়গুলো প্রয়োজন:
- কখন আপডেট করা হবে তা স্থির করুন। যেহেতু A/B আপডেটগুলো ব্যাকগ্রাউন্ডে সম্পন্ন হয়, তাই এগুলো আর ব্যবহারকারীর ইচ্ছাধীন থাকে না। ব্যবহারকারীদের অসুবিধা এড়ানোর জন্য, ডিভাইসটি যখন নিষ্ক্রিয় রক্ষণাবেক্ষণ মোডে থাকে, যেমন সারারাত, এবং ওয়াই-ফাই-এর সাথে সংযুক্ত থাকে, তখন আপডেটগুলো শিডিউল করার পরামর্শ দেওয়া হয়। তবে, আপনার ক্লায়েন্ট আপনার ইচ্ছামতো যেকোনো হিউরিস্টিকস ব্যবহার করতে পারে।
- আপনার OTA প্যাকেজ সার্ভারগুলির সাথে যোগাযোগ করে কোনো আপডেট উপলব্ধ আছে কিনা তা নির্ধারণ করুন। এটি মূলত আপনার বিদ্যমান ক্লায়েন্ট কোডের মতোই হবে, তবে এক্ষেত্রে আপনাকে ডিভাইসটি A/B সমর্থন করে কিনা তা সংকেত দিতে হবে। (গুগলের ক্লায়েন্টে ব্যবহারকারীদের সর্বশেষ আপডেট পরীক্ষা করার জন্য একটি 'এখনই পরীক্ষা করুন' (Check now ) বাটনও রয়েছে।)
- আপনার আপডেট প্যাকেজের জন্য HTTPS URL ব্যবহার করে
update_engineকল করুন, যদি সেরকম কোনো প্যাকেজ উপলব্ধ থাকে।update_engineআপডেট প্যাকেজটি স্ট্রিম করার সাথে সাথে বর্তমানে অব্যবহৃত পার্টিশনের র ব্লকগুলো আপডেট করবে। -
update_engineরেজাল্ট কোডের উপর ভিত্তি করে আপনার সার্ভারগুলিতে ইনস্টলেশনের সাফল্য বা ব্যর্থতার রিপোর্ট করুন। যদি আপডেটটি সফলভাবে প্রয়োগ করা হয়, তাহলেupdate_engineপরবর্তী রিবুটে বুটলোডারকে নতুন OS-এ বুট করতে বলবে। নতুন OS বুট করতে ব্যর্থ হলে বুটলোডার পুরোনো OS-এ ফিরে যাবে, তাই ক্লায়েন্টের পক্ষ থেকে কোনো কাজ করার প্রয়োজন নেই। যদি আপডেটটি ব্যর্থ হয়, তাহলে বিস্তারিত এরর কোডের উপর ভিত্তি করে ক্লায়েন্টকে সিদ্ধান্ত নিতে হবে যে কখন (এবং আদৌ) আবার চেষ্টা করা হবে। উদাহরণস্বরূপ, একজন বিচক্ষণ ক্লায়েন্ট বুঝতে পারবে যে একটি আংশিক ("diff") OTA প্যাকেজ ব্যর্থ হয়েছে এবং এর পরিবর্তে একটি সম্পূর্ণ OTA প্যাকেজ চেষ্টা করবে।
ঐচ্ছিকভাবে, ক্লায়েন্ট পারেন:
- ব্যবহারকারীকে রিবুট করতে বলার জন্য একটি নোটিফিকেশন দেখান। আপনি যদি এমন একটি নীতি প্রয়োগ করতে চান যেখানে ব্যবহারকারীকে নিয়মিত আপডেট করতে উৎসাহিত করা হয়, তাহলে এই নোটিফিকেশনটি আপনার ক্লায়েন্টে যোগ করা যেতে পারে। যদি ক্লায়েন্ট ব্যবহারকারীদের প্রম্পট না করে, তাহলেও ব্যবহারকারীরা পরেরবার রিবুট করার সময় আপডেটটি পেয়ে যাবেন। (গুগলের ক্লায়েন্টে প্রতিটি আপডেটের জন্য একটি কনফিগারযোগ্য বিলম্বের ব্যবস্থা রয়েছে।)
- ব্যবহারকারীদের একটি নোটিফিকেশন দেখিয়ে জানান যে তারা নতুন ওএস সংস্করণে বুট করেছেন, নাকি তা করার কথা থাকলেও পুরোনো ওএস সংস্করণে ফিরে গেছেন। (গুগলের ক্লায়েন্ট সাধারণত এর কোনোটিই করে না।)
সিস্টেমের দিক থেকে, A/B সিস্টেম আপডেট নিম্নলিখিত বিষয়গুলোকে প্রভাবিত করে:
- পার্টিশন নির্বাচন (স্লট),
update_engineডেমন, এবং বুটলোডার ইন্টারঅ্যাকশন (যা নিচে বর্ণনা করা হয়েছে) - বিল্ড প্রক্রিয়া এবং OTA আপডেট প্যাকেজ তৈরি (যা 'A/B আপডেট বাস্তবায়ন ' অংশে বর্ণিত আছে)
পার্টিশন নির্বাচন (স্লট)
A/B সিস্টেম আপডেটে স্লট (সাধারণত স্লট A এবং স্লট B) নামে পরিচিত দুই সেট পার্টিশন ব্যবহৃত হয়। সিস্টেমটি বর্তমান স্লট থেকে চলে, এবং স্বাভাবিক কার্যক্রমের সময় অব্যবহৃত স্লটের পার্টিশনগুলো চলমান সিস্টেম দ্বারা অ্যাক্সেস করা হয় না। এই পদ্ধতিটি অব্যবহৃত স্লটকে একটি ফলব্যাক হিসেবে রেখে আপডেটকে ত্রুটি-প্রতিরোধী করে তোলে: যদি কোনো আপডেটের সময় বা ঠিক পরেই কোনো ত্রুটি ঘটে, তবে সিস্টেমটি পুরোনো স্লটে রোলব্যাক করতে পারে এবং একটি সচল সিস্টেম চালু রাখতে পারে। এই লক্ষ্য অর্জনের জন্য, OTA আপডেটের অংশ হিসেবে বর্তমান স্লট দ্বারা ব্যবহৃত কোনো পার্টিশন আপডেট করা উচিত নয় (এমনকি সেইসব পার্টিশনও যার কেবল একটি কপি রয়েছে)।
প্রতিটি স্লটের একটি বুটেবল অ্যাট্রিবিউট থাকে, যা নির্দেশ করে যে স্লটটিতে ডিভাইসটি বুট করার জন্য সঠিক সিস্টেম আছে কিনা। সিস্টেম চালু থাকা অবস্থায় বর্তমান স্লটটি বুটেবল হয়, কিন্তু অন্য স্লটে সিস্টেমের একটি পুরোনো (তবে সঠিক) সংস্করণ, একটি নতুন সংস্করণ, বা অবৈধ ডেটা থাকতে পারে। বর্তমান স্লট যা-ই হোক না কেন, একটি স্লট থাকে যা অ্যাক্টিভ স্লট (যেটি থেকে বুটলোডার পরবর্তী বুটে বুট করবে) বা প্রিফার্ড স্লট।
প্রতিটি স্লটের একটি 'সফল' অ্যাট্রিবিউটও থাকে, যা ইউজার স্পেস দ্বারা সেট করা হয় এবং এটি কেবল তখনই প্রাসঙ্গিক যখন স্লটটি বুটেবল হয়। একটি সফল স্লট বুট করতে, চলতে এবং নিজেকে আপডেট করতে সক্ষম হওয়া উচিত। একটি বুটেবল স্লট, যা থেকে বুট করার বেশ কয়েকটি চেষ্টার পরেও সফল হিসেবে চিহ্নিত হয়নি, সেটিকে বুটলোডার দ্বারা 'আনবুটেবল' হিসেবে চিহ্নিত করা উচিত। এর মধ্যে সক্রিয় স্লটটিকে অন্য একটি বুটেবল স্লটে পরিবর্তন করাও অন্তর্ভুক্ত (সাধারণত নতুন, সক্রিয় স্লটটিতে বুট করার চেষ্টার ঠিক আগে যে স্লটটি চলছিল, সেটিতে)। ইন্টারফেসের নির্দিষ্ট বিবরণ boot_control.h ফাইলে সংজ্ঞায়িত করা আছে।
ইঞ্জিন ডেমন আপডেট করুন
A/B সিস্টেম আপডেট করার জন্য, সিস্টেমকে একটি নতুন ও হালনাগাদ সংস্করণে বুট করার জন্য প্রস্তুত করতে update_engine নামক একটি ব্যাকগ্রাউন্ড ডেমন ব্যবহৃত হয়। এই ডেমনটি নিম্নলিখিত কাজগুলো সম্পাদন করতে পারে:
- OTA প্যাকেজের নির্দেশনা অনুযায়ী বর্তমান স্লট A/B পার্টিশনগুলো থেকে ডেটা পড়ুন এবং অব্যবহৃত স্লট A/B পার্টিশনগুলোতে যেকোনো ডেটা লিখুন।
- একটি পূর্ব-নির্ধারিত ওয়ার্কফ্লোতে
boot_controlইন্টারফেসটি কল করুন। - OTA প্যাকেজের নির্দেশনা অনুযায়ী, সমস্ত অব্যবহৃত স্লট পার্টিশন লেখার পর নতুন পার্টিশন থেকে একটি পোস্ট-ইনস্টল প্রোগ্রাম চালান। (বিস্তারিত জানতে, পোস্ট-ইনস্টলেশন দেখুন)।
যেহেতু update_engine ডেমনটি সরাসরি বুট প্রক্রিয়ার সাথে জড়িত নয়, তাই আপডেটের সময় এর কার্যকলাপ বর্তমান স্লটের SELinux পলিসি এবং ফিচার দ্বারা সীমাবদ্ধ থাকে (সিস্টেম নতুন সংস্করণে বুট না করা পর্যন্ত এই ধরনের পলিসি এবং ফিচার আপডেট করা যায় না)। একটি শক্তিশালী সিস্টেম বজায় রাখার জন্য, আপডেট প্রক্রিয়াটির পার্টিশন টেবিল, বর্তমান স্লটের পার্টিশনগুলোর বিষয়বস্তু, অথবা ফ্যাক্টরি রিসেট দ্বারা মুছে ফেলা যায় না এমন নন-A/B পার্টিশনগুলোর বিষয়বস্তু পরিবর্তন করা উচিত নয় ।
ইঞ্জিন উৎস আপডেট করুন
update_engine সোর্সটি system/update_engine এ অবস্থিত। A/B OTA dexopt ফাইলগুলো installd এবং একটি প্যাকেজ ম্যানেজারের মধ্যে বিভক্ত:
-
frameworks/native/cmds/installd/ota* এর মধ্যে পোস্টইনস্টল স্ক্রিপ্ট, chroot-এর জন্য বাইনারি, dex2oat-কে কল করা installd ক্লোন, পোস্ট-OTA মুভ-আর্টিফ্যাক্টস স্ক্রিপ্ট এবং মুভ স্ক্রিপ্টের জন্য rc ফাইল অন্তর্ভুক্ত রয়েছে। -
frameworks/base/services/core/java/com/android/server/pm/OtaDexoptService.java(এবংOtaDexoptShellCommand) হলো প্যাকেজ ম্যানেজার যা অ্যাপ্লিকেশনগুলির জন্য dex2oat কমান্ড প্রস্তুত করে।
একটি কার্যকর উদাহরণের জন্য, /device/google/marlin/device-common.mk দেখুন।
ইঞ্জিন লগ আপডেট করুন
Android 8.x রিলিজ এবং তার আগের সংস্করণগুলোর জন্য, update_engine লগগুলো logcat এবং বাগ রিপোর্টে পাওয়া যাবে। ফাইল সিস্টেমে update_engine লগগুলো উপলব্ধ করতে, আপনার বিল্ডে নিম্নলিখিত পরিবর্তনগুলো প্যাচ করুন:
- ৪৮৬৬১৮ পরিবর্তন করুন
- ৫২৯০৮০ পরিবর্তন করুন
- ৫২৯০৮১ পরিবর্তন করুন
- ৫৩৪৬৬০ পরিবর্তন করুন
- ৫৯৪৬৩৭ পরিবর্তন করুন
এই পরিবর্তনগুলি সর্বশেষ update_engine লগের একটি অনুলিপি /data/misc/update_engine_log/update_engine. YEAR - TIME সংরক্ষণ করে। বর্তমান লগ ছাড়াও, সর্বশেষ পাঁচটি লগ /data/misc/update_engine_log/ অধীনে সংরক্ষিত হয়। লগ গ্রুপ আইডি সহ ব্যবহারকারীরা ফাইল সিস্টেম লগগুলি অ্যাক্সেস করতে পারবেন।
বুটলোডার মিথস্ক্রিয়া
boot_control HAL-টি update_engine (এবং সম্ভবত অন্যান্য ডেমন) দ্বারা ব্যবহৃত হয় বুটলোডারকে নির্দেশ দেওয়ার জন্য যে কোথা থেকে বুট করতে হবে। সাধারণ উদাহরণমূলক পরিস্থিতি এবং তাদের সংশ্লিষ্ট অবস্থাগুলো নিম্নরূপ:
- সাধারণ অবস্থা : সিস্টেমটি তার বর্তমান স্লট, অর্থাৎ স্লট A বা B থেকে চলছে। এখন পর্যন্ত কোনো আপডেট প্রয়োগ করা হয়নি। সিস্টেমের বর্তমান স্লটটি বুটেবল, সফল এবং সক্রিয় স্লট।
- আপডেট চলছে : সিস্টেমটি স্লট B থেকে চলছে, তাই স্লট B হলো বুটযোগ্য, সফল এবং সক্রিয় স্লট। স্লট A-কে আনবুটেবল হিসেবে চিহ্নিত করা হয়েছে, কারণ এর বিষয়বস্তু আপডেট করা হচ্ছে কিন্তু এখনও সম্পূর্ণ হয়নি। এই অবস্থায় রিবুট করলে তা স্লট B থেকেই বুট হওয়া চালিয়ে যাবে।
- আপডেট প্রয়োগ করা হয়েছে, রিবুট বাকি আছে : সিস্টেমটি স্লট B থেকে চলছে, স্লট B বুটযোগ্য এবং সফল, কিন্তু স্লট A সক্রিয় হিসাবে চিহ্নিত করা হয়েছে (এবং তাই বুটযোগ্য হিসাবে চিহ্নিত)। স্লট A এখনও সফল হিসাবে চিহ্নিত করা হয়নি এবং বুটলোডার দ্বারা স্লট A থেকে বুট করার জন্য কিছু সংখ্যক প্রচেষ্টা করা উচিত।
- নতুন আপডেটে সিস্টেম রিবুট হয়েছে : সিস্টেমটি প্রথমবারের জন্য স্লট A থেকে চলছে, স্লট B এখনও বুটেবল এবং সফল, যেখানে স্লট A শুধুমাত্র বুটেবল ও সক্রিয় থাকলেও সফল নয়। কিছু যাচাই-বাছাই করার পর, একটি ইউজার স্পেস ডেমন,
update_verifier, স্লট A-কে সফল হিসেবে চিহ্নিত করবে।
স্ট্রিমিং আপডেট সমর্থন
ব্যবহারকারীর ডিভাইসে আপডেট প্যাকেজ ডাউনলোড করার জন্য /data পার্টিশনে সবসময় পর্যাপ্ত জায়গা থাকে না। যেহেতু OEM বা ব্যবহারকারী কেউই /cache পার্টিশনে জায়গা নষ্ট করতে চান না, তাই কিছু ব্যবহারকারী আপডেট পান না, কারণ ডিভাইসে আপডেট প্যাকেজ সংরক্ষণ করার কোনো জায়গা থাকে না। এই সমস্যা সমাধানের জন্য, অ্যান্ড্রয়েড ৮.০-তে স্ট্রিমিং A/B আপডেটের সুবিধা যোগ করা হয়েছে, যা ডাউনলোড হওয়ার সাথে সাথেই ব্লকগুলোকে /data তে সংরক্ষণ না করে সরাসরি B পার্টিশনে লিখে দেয়। স্ট্রিমিং A/B আপডেটের জন্য প্রায় কোনো টেম্পোরারি স্টোরেজের প্রয়োজন হয় না এবং এতে কেবল প্রায় ১০০ KiB মেটাডেটার জন্য যথেষ্ট স্টোরেজ লাগে।
অ্যান্ড্রয়েড ৭.১-এ স্ট্রিমিং আপডেট চালু করতে, নিম্নলিখিত প্যাচগুলি চেরিপিক করুন:
- একটি প্রক্সি রেজোলিউশন অনুরোধ বাতিল করার অনুমতি দিন
- প্রক্সি রিজলভ করার সময় ট্রান্সফার বন্ধ হয়ে যাওয়ার সমস্যাটি সমাধান করুন
- রেঞ্জগুলির মধ্যে TerminateTransfer-এর জন্য ইউনিট টেস্ট যোগ করুন।
- RetryTimeoutCallback() পরিষ্কার করুন
গুগল মোবাইল সার্ভিসেস (জিএমএস) বা অন্য কোনো আপডেট ক্লায়েন্ট ব্যবহার করে অ্যান্ড্রয়েড ৭.১ এবং তার পরবর্তী সংস্করণগুলোতে স্ট্রিমিং এ/বি আপডেট সমর্থন করার জন্য এই প্যাচগুলো প্রয়োজন।
একটি A/B আপডেটের জীবনকাল
যখন একটি OTA প্যাকেজ (কোডে যাকে পেলোড বলা হয়) ডাউনলোডের জন্য উপলব্ধ হয়, তখন আপডেট প্রক্রিয়া শুরু হয়। ডিভাইসের পলিসিগুলো ব্যাটারির স্তর, ব্যবহারকারীর কার্যকলাপ, চার্জিং স্ট্যাটাস বা অন্যান্য নীতির উপর ভিত্তি করে পেলোড ডাউনলোড এবং প্রয়োগকে স্থগিত করতে পারে। এছাড়াও, যেহেতু আপডেটটি ব্যাকগ্রাউন্ডে চলে, তাই ব্যবহারকারীরা হয়তো জানতেও পারেন না যে একটি আপডেট চলছে। এই সবকিছুর অর্থ হলো, পলিসি, অপ্রত্যাশিত রিবুট বা ব্যবহারকারীর কার্যকলাপের কারণে আপডেট প্রক্রিয়াটি যেকোনো মুহূর্তে বাধাগ্রস্ত হতে পারে।
ঐচ্ছিকভাবে, OTA প্যাকেজের মধ্যেই থাকা মেটাডেটা নির্দেশ করে যে আপডেটটি স্ট্রিম করা যাবে; একই প্যাকেজ নন-স্ট্রিমিং ইনস্টলেশনের জন্যও ব্যবহার করা যেতে পারে। সার্ভার ক্লায়েন্টকে এটি স্ট্রিমিং হচ্ছে তা জানানোর জন্য মেটাডেটা ব্যবহার করতে পারে, যাতে ক্লায়েন্ট সঠিকভাবে OTA-টি update_engine এর কাছে হস্তান্তর করে। যেসব ডিভাইস প্রস্তুতকারকের নিজস্ব সার্ভার এবং ক্লায়েন্ট রয়েছে, তারা স্ট্রিমিং আপডেট চালু করতে পারে এটা নিশ্চিত করার মাধ্যমে যে, সার্ভার যেন আপডেটটিকে স্ট্রিমিং হিসেবে শনাক্ত করে (অথবা ধরে নেয় যে সব আপডেটই স্ট্রিমিং) এবং ক্লায়েন্ট যেন স্ট্রিমিংয়ের জন্য update_engine কে সঠিক কলটি করে। প্রস্তুতকারকরা প্যাকেজটি যে স্ট্রিমিং ভ্যারিয়েন্টের, সেই তথ্য ব্যবহার করে ক্লায়েন্টের কাছে একটি ফ্ল্যাগ পাঠাতে পারে, যা ফ্রেমওয়ার্কের কাছে স্ট্রিমিং হিসেবে হস্তান্তরের প্রক্রিয়াটি ট্রিগার করবে।
পেলোড উপলব্ধ হওয়ার পর, আপডেট প্রক্রিয়াটি নিম্নরূপ:
| ধাপ | কার্যকলাপ |
|---|---|
| ১ | বর্তমান স্লটটি (বা "সোর্স স্লট") markBootSuccessful() ব্যবহার করে সফল হিসেবে চিহ্নিত করা হয় (যদি আগে থেকে চিহ্নিত না থাকে)। |
| ২ | setSlotAsUnbootable() ফাংশনটি কল করার মাধ্যমে অব্যবহৃত স্লটটিকে (বা "টার্গেট স্লট") আনবুটেবল হিসেবে চিহ্নিত করা হয়। আপডেটের শুরুতে বর্তমান স্লটটিকে সর্বদা সফল হিসেবে চিহ্নিত করা হয়, যাতে বুটলোডার অব্যবহৃত স্লটে ফিরে না যায়, কারণ সেই স্লটে শীঘ্রই অবৈধ ডেটা জমা হবে। যদি সিস্টেমটি আপডেট প্রয়োগ করা শুরু করার মতো পর্যায়ে পৌঁছে যায়, তবে অন্যান্য প্রধান কম্পোনেন্টগুলো (যেমন ক্র্যাশ লুপে থাকা UI) অকার্যকর থাকলেও বর্তমান স্লটটিকে সফল হিসেবে চিহ্নিত করা হয়, কারণ এই সমস্যাগুলো সমাধানের জন্য নতুন সফটওয়্যার পুশ করা সম্ভব।আপডেট পেলোড হলো একটি অস্বচ্ছ ব্লব, যাতে নতুন সংস্করণে আপডেট করার নির্দেশাবলী থাকে। আপডেট পেলোডটি নিম্নলিখিত বিষয়গুলো নিয়ে গঠিত:
|
| ৩ | পেলোড মেটাডেটা ডাউনলোড করা হয়েছে। |
| ৪ | মেটাডেটাতে সংজ্ঞায়িত প্রতিটি অপারেশনের জন্য, ক্রমানুসারে, সংশ্লিষ্ট ডেটা (যদি থাকে) মেমরিতে ডাউনলোড করা হয়, অপারেশনটি প্রয়োগ করা হয় এবং সংশ্লিষ্ট মেমরি বাতিল করা হয়। |
| ৫ | সম্পূর্ণ পার্টিশনগুলো পুনরায় পড়া হয় এবং প্রত্যাশিত হ্যাশের সাথে মিলিয়ে যাচাই করা হয়। |
| ৬ | ইনস্টলেশন-পরবর্তী ধাপটি (যদি থাকে) চালানো হয়। যেকোনো ধাপ সম্পাদনের সময় কোনো ত্রুটি ঘটলে, আপডেটটি ব্যর্থ হয় এবং সম্ভবত একটি ভিন্ন পেলোড দিয়ে পুনরায় চেষ্টা করা হয়। যদি এ পর্যন্ত সমস্ত ধাপ সফল হয়, তাহলে আপডেটটি সফল হয় এবং শেষ ধাপটি সম্পাদিত হয়। |
| ৭ | setActiveBootSlot() কল করার মাধ্যমে অব্যবহৃত স্লটটিকে সক্রিয় হিসেবে চিহ্নিত করা হয়। অব্যবহৃত স্লটটিকে সক্রিয় হিসেবে চিহ্নিত করার অর্থ এই নয় যে এটির বুটিং প্রক্রিয়া সম্পন্ন হবে। যদি বুটলোডার (বা সিস্টেম নিজেই) একটি সফল অবস্থা শনাক্ত করতে না পারে, তবে এটি সক্রিয় স্লটটিকে আবার আগের অবস্থায় ফিরিয়ে দিতে পারে। |
| ৮ | ইনস্টলেশন-পরবর্তী ধাপে (যা নিচে বর্ণনা করা হয়েছে), পুরোনো ভার্সনে চলমান থাকা অবস্থাতেই "নতুন আপডেট" ভার্সনের একটি প্রোগ্রাম চালানো হয়। যদি OTA প্যাকেজে এটি সংজ্ঞায়িত করা থাকে, তবে এই ধাপটি বাধ্যতামূলক এবং প্রোগ্রামটিকে অবশ্যই এক্সিট কোড 0 সহ রিটার্ন করতে হবে; অন্যথায়, আপডেটটি ব্যর্থ হয়। | ৯ | সিস্টেমটি নতুন স্লটে সফলভাবে বুট হয়ে যথেষ্ট অগ্রসর হওয়ার পর এবং রিবুট-পরবর্তী পরীক্ষাগুলো শেষ করলে, markBootSuccessful() কল করার মাধ্যমে বর্তমান স্লটটিকে (যা আগে "টার্গেট স্লট" ছিল) সফল হিসেবে চিহ্নিত করা হয়। |
ইনস্টলেশন পরবর্তী
প্রতিটি পার্টিশনের জন্য যেখানে একটি পোস্ট-ইনস্টল ধাপ সংজ্ঞায়িত করা আছে, update_engine নতুন পার্টিশনটিকে একটি নির্দিষ্ট স্থানে মাউন্ট করে এবং মাউন্ট করা পার্টিশনের সাপেক্ষে OTA-তে নির্দিষ্ট করা প্রোগ্রামটি কার্যকর করে। উদাহরণস্বরূপ, যদি সিস্টেম পার্টিশনে পোস্ট-ইনস্টল প্রোগ্রামটি usr/bin/postinstall হিসাবে সংজ্ঞায়িত করা থাকে, তাহলে অব্যবহৃত স্লট থেকে এই পার্টিশনটি একটি নির্দিষ্ট স্থানে (যেমন /postinstall_mount ) মাউন্ট করা হবে এবং /postinstall_mount/usr/bin/postinstall কমান্ডটি কার্যকর করা হবে।
পোস্ট-ইনস্টলেশন সফল হওয়ার জন্য, পুরোনো কার্নেলটিকে অবশ্যই নিম্নলিখিত কাজগুলো করতে সক্ষম হতে হবে:
- নতুন ফাইলসিস্টেম ফরম্যাটটি মাউন্ট করুন । পুরোনো কার্নেলে এর জন্য সমর্থন না থাকলে ফাইলসিস্টেমের ধরন পরিবর্তন করা যাবে না; এর মধ্যে ব্যবহৃত কম্প্রেশন অ্যালগরিদমের মতো বিবরণও অন্তর্ভুক্ত, যদি কোনো কম্প্রেসড ফাইলসিস্টেম (যেমন SquashFS) ব্যবহার করা হয়।
- নতুন পার্টিশনের পোস্ট-ইনস্টল প্রোগ্রামের ফরম্যাটটি বুঝুন । যদি একটি এক্সিকিউটেবল অ্যান্ড লিঙ্কেবল ফরম্যাট (ELF) বাইনারি ব্যবহার করা হয়, তবে এটি পুরানো কার্নেলের সাথে সামঞ্জস্যপূর্ণ হওয়া উচিত (যেমন, যদি আর্কিটেকচার ৩২-বিট থেকে ৬৪-বিট বিল্ডে পরিবর্তিত হয়, তবে একটি পুরানো ৩২-বিট কার্নেলে একটি ৬৪-বিট নতুন প্রোগ্রাম চালানো)। লোডারকে (
ld) অন্য পাথ ব্যবহার করতে বা একটি স্ট্যাটিক বাইনারি তৈরি করতে নির্দেশ না দেওয়া হলে, লাইব্রেরিগুলি নতুন সিস্টেম ইমেজ থেকে নয়, বরং পুরানো সিস্টেম ইমেজ থেকে লোড হবে।
উদাহরণস্বরূপ, আপনি একটি শেল স্ক্রিপ্টকে পোস্ট-ইনস্টল প্রোগ্রাম হিসেবে ব্যবহার করতে পারেন (যার শুরুতে একটি #! চিহ্ন থাকবে এবং যা পুরোনো সিস্টেমের শেল বাইনারি দ্বারা ইন্টারপ্রেট করা হবে), তারপর আরও জটিল একটি বাইনারি পোস্ট-ইনস্টল প্রোগ্রাম চালানোর জন্য নতুন পরিবেশ থেকে লাইব্রেরি পাথ সেট আপ করতে পারেন। বিকল্পভাবে, আপনি একটি ডেডিকেটেড ছোট পার্টিশন থেকে পোস্ট-ইনস্টল ধাপটি চালাতে পারেন, যাতে ব্যাকওয়ার্ড কম্প্যাটিবিলিটি সমস্যা বা স্টেপিং-স্টোন আপডেট ছাড়াই মূল সিস্টেম পার্টিশনের ফাইলসিস্টেম ফরম্যাট আপডেট করা যায়; এর ফলে ব্যবহারকারীরা একটি ফ্যাক্টরি ইমেজ থেকে সরাসরি সর্বশেষ সংস্করণে আপডেট করতে পারবেন।
নতুন পোস্ট-ইনস্টল প্রোগ্রামটি পুরোনো সিস্টেমে সংজ্ঞায়িত SELinux পলিসি দ্বারা সীমাবদ্ধ। সেই হিসেবে, পোস্ট-ইনস্টল ধাপটি কোনো নির্দিষ্ট ডিভাইসে ডিজাইন অনুযায়ী প্রয়োজনীয় কাজ বা অন্যান্য বেস্ট-এফোর্ট টাস্ক সম্পাদনের জন্য উপযুক্ত। রিবুটের আগে এককালীন বাগ ফিক্সের জন্য, যার জন্য অপ্রত্যাশিত অনুমতির প্রয়োজন হয়, পোস্ট-ইনস্টল ধাপটি উপযুক্ত নয় ।
নির্বাচিত পোস্ট-ইনস্টল প্রোগ্রামটি postinstall SELinux কনটেক্সটে চলে। নতুন সিস্টেমে রিবুট করার পর, নতুন মাউন্ট করা পার্টিশনের সমস্ত ফাইলকে postinstall_file ট্যাগ দিয়ে চিহ্নিত করা হবে, সেগুলোর অ্যাট্রিবিউট যা-ই হোক না কেন। নতুন সিস্টেমে SELinux অ্যাট্রিবিউটে করা কোনো পরিবর্তন পোস্ট-ইনস্টল ধাপকে প্রভাবিত করবে না। যদি পোস্ট-ইনস্টল প্রোগ্রামের অতিরিক্ত অনুমতির প্রয়োজন হয়, তবে সেগুলো অবশ্যই পোস্ট-ইনস্টল কনটেক্সটে যোগ করতে হবে।
রিবুট করার পরে
রিবুট করার পর, update_verifier dm-verity ব্যবহার করে ইন্টিগ্রিটি চেক শুরু করে। এই চেকটি জাইগোট (zygote)-এর আগে শুরু হয়, যাতে জাভা সার্ভিসগুলো এমন কোনো অপরিবর্তনীয় পরিবর্তন করতে না পারে যা একটি নিরাপদ রোলব্যাককে বাধা দেবে। এই প্রক্রিয়া চলাকালীন, যদি ভেরিফাইড বুট বা dm-verity কোনো করাপশন শনাক্ত করে, তবে বুটলোডার এবং কার্নেলও রিবুট শুরু করতে পারে। চেকটি সম্পন্ন হওয়ার পর, update_verifier বুটটিকে সফল হিসেবে চিহ্নিত করে।
update_verifier শুধুমাত্র /data/ota_package/care_map.txt এ তালিকাভুক্ত ব্লকগুলি পড়বে, যা AOSP কোড ব্যবহার করার সময় একটি A/B OTA প্যাকেজের অন্তর্ভুক্ত থাকে। জাভা সিস্টেম আপডেট ক্লায়েন্ট, যেমন GmsCore, care_map.txt ফাইলটি এক্সট্র্যাক্ট করে, ডিভাইসটি রিবুট করার আগে অ্যাক্সেস পারমিশন সেট আপ করে এবং সিস্টেমটি সফলভাবে নতুন সংস্করণে বুট করার পরে এক্সট্র্যাক্ট করা ফাইলটি মুছে ফেলে।