ভার্চুয়াল A/B ওভারভিউ

ভার্চুয়াল A/B হল Android-এর প্রধান আপডেট মেকানিজম। ভার্চুয়াল A/B, লিগ্যাসি A/B আপডেট (A/B সিস্টেম আপডেট দেখুন) এবং নন-A/B-এর উপরে তৈরি করা হয়, যা আপডেটের জন্য প্রয়োজনীয় স্পেস কমাতে 15-এ বাতিল করা হয়েছে।

ভার্চুয়াল A/B-তে ডায়নামিক পার্টিশনের জন্য অতিরিক্ত স্লট থাকে না, দেখুন ডায়নামিক পার্টিশন। এর পরিবর্তে, ডেল্টা স্ন্যাপশটে লেখা হয় এবং তারপরে সফল বুট কনফার্ম করার পরে বেস পার্টিশনে মার্জ করা হয়। ভার্চুয়াল A/B, Android-এর জন্য নির্দিষ্ট স্ন্যাপশট ফর্ম্যাট ব্যবহার করে। কমপ্রেস করা স্ন্যাপশটের জন্য COW ফর্ম্যাট দেখুন যা স্ন্যাপশট কমপ্রেস করতে এবং ডিস্ক স্টোরেজে খালি জায়গা ব্যবহার কমাতে সাহায্য করে। সম্পূর্ণ OTA-তে কম্প্রেশনের মাধ্যমে স্ন্যাপশটের সাইজ প্রায় ৪৫% কমানো হয় এবং ইনক্রিমেন্টাল OTA স্ন্যাপশটের সাইজ প্রায় ৫৫% কমানো হয়।

Android 12-এ স্ন্যাপশট করা পার্টিশন কম্প্রেস করার জন্য ভার্চুয়াল A/B কম্প্রেশনের বিকল্প অফার করা হয়। ভার্চুয়াল A/B টেস্টিং নিম্নলিখিত সুবিধা দেয়

  • ভার্চুয়াল A/B আপডেট হল নির্বিঘ্ন (ডিভাইস চালু থাকাকালীন সম্পূর্ণ আপডেট ব্যাকগ্রাউন্ডে হয়) যেমন A/B আপডেট। ভার্চুয়াল A/B আপডেট ডিভাইসের অফলাইন থাকার এবং ব্যবহারযোগ্য না থাকার সময়কে কমিয়ে দেয়।
  • ভার্চুয়াল A/B আপডেট রোল ব্যাক করা যেতে পারে। নতুন OS বুট করতে না পারলে, ডিভাইস অটোমেটিক আগের ভার্সনে ফিরে যায়।
  • ভার্চুয়াল A/B আপডেট ন্যূনতম অতিরিক্ত স্পেস ব্যবহার করে, কারণ এটি শুধুমাত্র বুটলোডার ব্যবহার করা পার্টিশন ডুপ্লিকেট করে। অন্যান্য আপডেট করা যায় এমন পার্টিশন হল স্ন্যাপশট নেওয়া।

ব্যাকগ্রাউন্ড ও পরিভাষা

এই বিভাগে ভার্চুয়াল A/B-কে সাপোর্ট করে এমন প্রযুক্তি ও পরিভাষার সংজ্ঞা দেওয়া হয়েছে। OTA ইনস্টলেশনের সময়, নতুন অপারেটিং সিস্টেম ডেটা হয় ফিজিক্যাল পার্টিশনের জন্য নতুন স্লটে লেখা হয় অথবা Android-নির্দিষ্ট COW ডিভাইসে লেখা হয়। ডিভাইস রিবুট করার পরে, dm-user এবং snapuserd ডেমন ব্যবহার করে ডায়নামিক পার্টিশন ডেটা বেস ডিভাইসে মার্জ করা হয়। এই প্রসেস সম্পূর্ণভাবে ব্যবহারকারীর স্পেসে হয়।

ডিভাইস-ম্যাপার

ডিভাইস-ম্যাপার হল একটি Linux ভার্চুয়াল ব্লক লেয়ার যা Android-এ প্রায়ই ব্যবহার করা হয়। ডায়নামিক পার্টিশন-এর মাধ্যমে, /system-এর মতো পার্টিশন হল লেয়ার করা ডিভাইসের স্ট্যাক:

  • স্ট্যাকের সবচেয়ে নিচে ফিজিক্যাল সুপার পার্টিশন থাকে (যেমন, /dev/block/by-name/super)।
  • মাঝখানে একটি dm-linear ডিভাইস আছে, যা সুপার পার্টিশনের কোন ব্লক প্রদত্ত ডায়নামিক পার্টিশন তৈরি করে তা নির্দিষ্ট করে। এটি A/B ডিভাইসে /dev/block/mapper/system_[a|b] হিসেবে অথবা নন-A/B ডিভাইসে /dev/block/mapper/system হিসেবে দেখা যায়।
  • সবচেয়ে উপরে যাচাই করা পার্টিশনের জন্য তৈরি করা dm-verity ডিভাইস থাকে। এই ডিভাইস যাচাই করে যে dm-linear ডিভাইসে ব্লকগুলি সঠিকভাবে সাইন করা হয়েছে। এটি /dev/block/mapper/system-verity হিসেবে দেখা যায় এবং /system মাউন্ট পয়েন্টের সোর্স।

/system মাউন্ট পয়েন্টের নিচে স্ট্যাকটি কেমন দেখতে হয় তা ১ নম্বর চিত্রে দেখানো হয়েছে।

সিস্টেমের নিচে পার্টিশন স্ট্যাকিং

ছবি ১. /system মাউন্ট পয়েন্টের নিচে স্ট্যাক করুন

কম্প্রেস করা স্ন্যাপশট

Android 12 ও তার পরবর্তী যেকোনও ভার্সনে, /data পার্টিশনে স্পেসের প্রয়োজনীয়তা বেশি হতে পারে বলে, আপনি নিজের বিল্ডে কম্প্রেস করা স্ন্যাপশট চালু করতে পারেন, যাতে /data পার্টিশনে স্পেসের প্রয়োজনীয়তা বেশি হলেও তা ম্যানেজ করা যায়।

Android 12 এবং তার পরবর্তী যেকোনও ভার্সনে উপলভ্য নিম্নলিখিত কম্পোনেন্টের উপর ভিত্তি করে ভার্চুয়াল A/B কম্প্রেসড স্ন্যাপশট তৈরি করা হয়:

  • dm-user, FUSE-এর মতো একটি কার্নেল মডিউল যা ব্লক ডিভাইস প্রয়োগ করার জন্য ইউজারস্পেসকে অনুমতি দেয়।
  • snapuserd, একটি নতুন স্ন্যাপশট ফর্ম্যাট প্রয়োগ করার জন্য একটি ব্যবহারকারীর স্পেস ডেমন।

এইসব কম্পোনেন্ট কম্প্রেশন চালু করে। কম্প্রেস করা স্ন্যাপশট সংক্রান্ত ক্ষমতা প্রয়োগ করার জন্য অন্যান্য প্রয়োজনীয় পরিবর্তন করা হয়েছে, যা পরবর্তী বিভাগে উল্লেখ করা হয়েছে: কম্প্রেস করা স্ন্যাপশটের জন্য COW ফর্ম্যাট, dm-user এবং snapuserd।

কম্প্রেস করা স্ন্যাপশটের জন্য COW ফর্ম্যাট

Android 12 ও তার পরবর্তী যেকোনও ভার্সনে, কম্প্রেস করা স্ন্যাপশট Android-এর জন্য নির্দিষ্ট COW ফর্ম্যাট ব্যবহার করে। COW ফর্ম্যাটে OTA সম্পর্কে মেটাডেটা থাকে এবং এতে COW অপারেশন ও নতুন অপারেটিং সিস্টেম ডেটা সহ আলাদা বাফার থাকে। শুধুমাত্র replace অপারেশন (স্ন্যাপশটে ব্লক Y-এর কন্টেন্ট দিয়ে বেস ইমেজে ব্লক X রিপ্লেস করা) করার অনুমতি দেয় এমন কার্নেল স্ন্যাপশট ফর্ম্যাটের তুলনায়, Android কম্প্রেসড স্ন্যাপশট COW ফর্ম্যাট আরও বেশি এক্সপ্রেসিভ এবং নিম্নলিখিত অপারেশনগুলি কাজ করে:

  • কপি করুন: বেস ডিভাইসে ব্লক X-এর জায়গায় বেস ডিভাইসে ব্লক Y বসাতে হবে।
  • পরিবর্তন করুন: বেস ডিভাইসের X ব্লকটি স্ন্যাপশটের Y ব্লকের কন্টেন্ট দিয়ে পরিবর্তন করতে হবে। এইসব ব্লক gz কম্প্রেস করা হয়।
  • জিরো: বেস ডিভাইসে ব্লক করা X-এর জায়গায় সব শূন্য বসাতে হবে।
  • XOR: COW ডিভাইস ব্লক X এবং ব্লক Y-এর মধ্যে XOR কম্প্রেস করা বাইট সেভ করে। (Android 13 ও তার পরবর্তী যেকোনও ভার্সনে উপলভ্য।)

সম্পূর্ণ OTA আপডেটে শুধুমাত্র রিপ্লেস ও জিরো অপারেশন থাকে। ইনক্রিমেন্টাল OTA আপডেটে অতিরিক্ত কপি অপারেশন থাকতে পারে।

ডিস্কে সম্পূর্ণ স্ন্যাপশট লেআউটটি দেখতে এইরকম:

কাউ ফর্ম্যাট

ছবি ২. ডিস্কে Android COW ফর্ম্যাট

dm-user

dm-user কার্নেল মডিউল userspace-কে ডিভাইস-ম্যাপার ব্লক ডিভাইস প্রয়োগ করতে সাহায্য করে। dm-user টেবিল এন্ট্রি /dev/dm-user/<control-name>-এর অধীনে একটি বিবিধ ডিভাইস তৈরি করে। কার্নেল থেকে রিড ও রাইট সংক্রান্ত অনুরোধ পাওয়ার জন্য userspace প্রসেস ডিভাইস পোল করতে পারে। প্রতিটি অনুরোধের সাথে একটি বাফার যুক্ত থাকে যা ব্যবহারকারীর স্পেসকে পপুলেট (পড়ার জন্য) বা প্রোপাগেট (লেখার জন্য) করে।

dm-user কার্নেল মডিউল কার্নেলের জন্য একটি নতুন ব্যবহারকারী-দৃশ্যমান ইন্টারফেস প্রদান করে যা আপস্ট্রিম kernel.org কোড বেসের অংশ নয়। এটি না হওয়া পর্যন্ত, Google-এর কাছে Android-এ dm-user ইন্টারফেস পরিবর্তন করার অধিকার সংরক্ষিত থাকে।

snapuserd

snapuserd userspace কম্পোনেন্ট dm-user ভার্চুয়াল A/B কম্প্রেশন প্রয়োগ করে। Snapuserd হল একটি ইউজারস্পেস ডেমোন যা Android COW ডিভাইস থেকে ডেটা লেখা ও পড়ার জন্য দায়ী। স্ন্যাপশটের সমস্ত I/O এই পরিষেবার মাধ্যমে যেতে হবে। OTA ইনস্টলেশনের সময়, নতুন অপারেটিং সিস্টেম ডেটা snapuserd-এর মাধ্যমে স্ন্যাপশটে লেখা হয় (কম্প্রেশন সহ)। মেটাডেটা পার্স করা এবং নতুন ব্লক ডেটা আনপ্যাক করার কাজও এখানেই ম্যানেজ করা হয়।

XOR কম্প্রেশন

Android 13 ও এর পরের যেকোনও ভার্সনে লঞ্চ করা ডিভাইসের জন্য, ডিফল্ট হিসেবে চালু থাকা XOR কম্প্রেশন ফিচার, ব্যবহারকারী স্পেস স্ন্যাপশটকে পুরনো ব্লক ও নতুন ব্লকের মধ্যে XOR কম্প্রেস করা বাইট সেভ করতে দেয়। ভার্চুয়াল A/B আপডেটে ব্লকের মাত্র কয়েকটি বাইট পরিবর্তন করা হলে, XOR কম্প্রেশন স্টোরেজ স্কিম ডিফল্ট স্টোরেজ স্কিমের তুলনায় কম জায়গা ব্যবহার করে কারণ স্ন্যাপশট সম্পূর্ণ ৪K বাইট স্টোর করে না। স্ন্যাপশটের সাইজ কমানো সম্ভব হয়েছে কারণ XOR ডেটাতে অনেক শূন্য থাকে এবং এটি কাঁচা ব্লক ডেটার তুলনায় সহজে কম্প্রেস করা যায়। Pixel ডিভাইসে, XOR কম্প্রেশন স্ন্যাপশটের সাইজ ২৫% থেকে ৪০% পর্যন্ত কমায়।

Android 13 ও এর পরের যেকোনও ভার্সনে আপগ্রেড করা ডিভাইসের জন্য, XOR কম্প্রেশন চালু করতে হবে। আরও জানতে, XOR কম্প্রেশন দেখুন।

স্ন্যাপশট মার্জ করা

Android 13 ও এর পরের যেকোনও ভার্সন সহ ডিভাইস লঞ্চ করার জন্য, ভার্চুয়াল A/B কম্প্রেশনে স্ন্যাপশট ও স্ন্যাপশট মার্জ করার প্রসেস snapuserd ইউজারস্পেস কম্পোনেন্ট দ্বারা পারফর্ম করা হয়। Android 13 ও এর পরের যেকোনও ভার্সনে আপগ্রেড করা ডিভাইসের জন্য, এই ফিচার চালু করতে হবে। বিস্তারিত জানতে, Userspace মার্জ দেখুন।

নিচে ভার্চুয়াল A/B কম্প্রেশন প্রসেস বর্ণনা করা হল:

  1. ফ্রেমওয়ার্ক dm-verity ডিভাইস থেকে /system পার্টিশন মাউন্ট করে, যা dm-user ডিভাইসের উপরে স্ট্যাক করা থাকে। এর অর্থ হল, রুট ফাইল সিস্টেম থেকে প্রতিটি I/O dm-user-এ রাউট করা হয়।
  2. dm-user I/O-কে userspace snapuserd ডেমনে রুট করে, যা I/O অনুরোধ হ্যান্ডেল করে।
  3. মার্জ অপারেশন সম্পূর্ণ হলে, ফ্রেমওয়ার্ক dm-linear (system_base)-এর উপরে dm-verity-কে কোলাপ্স করে এবং dm-user-কে সরিয়ে দেয়।

ভার্চুয়াল A/B কম্প্রেশন
প্রসেস

ছবি ৩. ভার্চুয়াল A/B কম্প্রেশন প্রসেস

স্ন্যাপশট মার্জ করার প্রসেস বিঘ্নিত হতে পারে। মার্জ করার প্রসেস চলাকালীন ডিভাইস রিবুট হয়ে গেলে, রিবুট হওয়ার পরে মার্জ করার প্রসেস আবার শুরু হয়।

Init ট্রানজিশন

কম্প্রেস করা স্ন্যাপশট দিয়ে বুট করার সময়, পার্টিশন মাউন্ট করার জন্য ফার্স্ট-স্টেজ ইনিটকে অবশ্যই snapuserd দিয়ে শুরু করতে হবে। এর ফলে একটি সমস্যা হয়: sepolicy লোড ও এনফোর্স করা হলে, snapuserd ভুল কনটেক্সটে চলে যায় এবং এর রিড অনুরোধ ব্যর্থ হয়, যার ফলে selinux অস্বীকার করে।

এটি সমাধান করতে, snapuserd init-এর সাথে লক-স্টেপে ট্রানজিশন করুন, যেমন:

  1. প্রথম-স্টেজ init র‍্যামডিস্ক থেকে snapuserd লঞ্চ করে এবং একটি এনভায়রনমেন্ট ভেরিয়েবলে একটি খোলা ফাইল-ডেসক্রিপ্টর সেভ করে।
  2. ফার্স্ট-স্টেজ init সিস্টেম পার্টিশনে রুট ফাইলসিস্টেম পরিবর্তন করে, তারপর init-এর সিস্টেম কপি এক্সিকিউট করে।
  3. init-এর সিস্টেম কপি, একত্রিত sepolicy-কে একটি স্ট্রিংয়ে পড়ে।
  4. Init সব ext4-ব্যাকড পৃষ্ঠায় mlock() ইনভোক করে। তারপর এটি স্ন্যাপশট ডিভাইসের জন্য সব ডিভাইস-ম্যাপার টেবিল বন্ধ করে দেয় এবং snapuserd বন্ধ করে দেয়। এর পরে পার্টিশন থেকে রিড করা নিষিদ্ধ, কারণ এটি করলে ডেডলক হয়।
  5. snapuserd-এর ramdisk কপির ওপেন ডেসক্রিপ্টর ব্যবহার করে, init সঠিক selinux কন্টেক্সটের সাথে ডেমনের আবার লঞ্চ করে। স্ন্যাপশট ডিভাইসের জন্য ডিভাইস-ম্যাপার টেবিল আবার অ্যাক্টিভেট করা হয়েছে।
  6. Init munlockall()-কে ইনভোক করে, এখন আবার IO পারফর্ম করা নিরাপদ।

স্পেস ব্যবহার

নিচের সারণীতে Pixel-এর OS ও OTA সাইজ ব্যবহার করে বিভিন্ন OTA মেকানিজমের জন্য স্পেস ব্যবহারের তুলনা করা হয়েছে।

আকার সংক্রান্ত প্রভাব নন-A/B A/B ভার্চুয়াল A/B ভার্চুয়াল A/B (কম্প্রেস করা)
ফ্যাক্টরির আসল ছবি ৪.৫ জিবি সুপার (৩.৮ জিবি ছবি + ৭০০ এমবি রিজার্ভ করা)১ ৯ জিবি সুপার (দুটি স্লটের জন্য ৩.৮ জিবি + ৭০০ এম রিজার্ভ করা আছে) ৪.৫ জিবি সুপার (৩.৮ জিবি ছবি + ৭০০ এমবি রিজার্ভ করা) ৪.৫ জিবি সুপার (৩.৮ জিবি ছবি + ৭০০ এমবি রিজার্ভ করা)
অন্যান্য স্ট্যাটিক পার্টিশন /cache কোনওটিই নয় কোনওটিই নয় কোনওটিই নয়
OTA চলাকালীন অতিরিক্ত স্টোরেজ (OTA প্রয়োগ করার পরে জায়গা ফিরিয়ে দেওয়া হয়) /data-তে ১.৪ জিবি 0 /data-তে 3.8GB2 /data-তে ২.১ জিবি২
OTA প্রয়োগ করার জন্য প্রয়োজনীয় মোট স্টোরেজ ৫.৯GB৩ (সুপার ও ডেটা) ৯ জিবি (সুপার) ৮.৩GB৩ (সুপার ও ডেটা) ৬.৬জিবি৩ (সুপার ও ডেটা)

১Pixel ম্যাপিংয়ের উপর ভিত্তি করে অনুমান করা লেআউট নির্দেশ করে।

২ধরে নেওয়া হয় যে নতুন সিস্টেম ইমেজটি আসলটির সমান সাইজের।

৩রিবুট না করা পর্যন্ত স্পেসের প্রয়োজনীয়তা সাময়িক।

Android 11 ভার্চুয়াল A/B

Virtual A/B-এর Android 11, Kernel COW ফর্ম্যাট ব্যবহার করে ডায়নামিক পার্টিশনে লিখেছে। এটি অবশেষে বন্ধ করে দেওয়া হয়েছে কারণ Kernel COW ফর্ম্যাট কম্প্রেশন কাজ করে না।

Android 12 Virtual A/B

Android 12-এ, Android-এর জন্য নির্দিষ্ট COW ফর্ম্যাটে কম্প্রেশন কাজ করে। Virtual A/B-এর এই ভার্সনে android নির্দিষ্ট COW-কে Kernel COW ফর্ম্যাটে অনুবাদ করতে হয়। অবশেষে এটি android 13-এ পরিবর্তন করা হয়েছে যা Kernel COW ফর্ম্যাটের উপর নির্ভরতা এবং dm-snapshot সরিয়ে দিয়েছে।

ভার্চুয়াল A/B প্রয়োগ করতে অথবা কম্প্রেস করা স্ন্যাপশট সংক্রান্ত ক্ষমতা ব্যবহার করতে, ভার্চুয়াল A/B প্রয়োগ করা দেখুন