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

অ্যান্ড্রয়েডের দুটি আপডেট প্রক্রিয়া রয়েছে: A/B (বিজোড়) আপডেট এবং নন-A/B আপডেট। কোড জটিলতা কমাতে এবং আপডেট প্রক্রিয়া উন্নত করতে, Android 11-এ দুটি প্রক্রিয়া ভার্চুয়াল A/B-এর মাধ্যমে একীভূত করা হয়েছে যাতে স্টোরেজের ন্যূনতম খরচ সহ সমস্ত ডিভাইসে বিরামহীন আপডেট আনা হয়। অ্যান্ড্রয়েড 12 স্ন্যাপশট করা পার্টিশনগুলিকে সংকুচিত করতে ভার্চুয়াল A/B কম্প্রেশনের বিকল্প অফার করে। Android 11 এবং Android 12 উভয় ক্ষেত্রেই নিম্নলিখিতগুলি প্রযোজ্য:

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

পটভূমি এবং পরিভাষা

এই বিভাগটি পরিভাষা সংজ্ঞায়িত করে এবং ভার্চুয়াল A/B সমর্থন করে এমন প্রযুক্তি বর্ণনা করে।

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

ডিভাইস-ম্যাপার হল একটি লিনাক্স ভার্চুয়াল ব্লক স্তর যা প্রায়শই অ্যান্ড্রয়েডে ব্যবহৃত হয়। গতিশীল পার্টিশনের সাথে, /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 মাউন্ট পয়েন্টের উৎস।

চিত্র 1 দেখায় যে /system মাউন্ট পয়েন্টের নীচে স্ট্যাকটি কেমন দেখাচ্ছে।

Partition stacking underneath system

চিত্র 1. /সিস্টেম মাউন্ট পয়েন্টের নীচে স্ট্যাক করুন

dm-স্ন্যাপশট

ভার্চুয়াল A/B dm-snapshot এর উপর নির্ভর করে, একটি স্টোরেজ ডিভাইসের অবস্থা স্ন্যাপশট করার জন্য একটি ডিভাইস-ম্যাপার মডিউল। dm-snapshot ব্যবহার করার সময়, প্লেতে চারটি ডিভাইস রয়েছে:

  • বেস ডিভাইস হল সেই ডিভাইস যা স্ন্যাপশট করা হয়েছে। এই পৃষ্ঠায়, বেস ডিভাইস সবসময় একটি গতিশীল পার্টিশন, যেমন সিস্টেম বা বিক্রেতা।
  • বেস ডিভাইসে পরিবর্তন লগিং করার জন্য কপি-অন-রাইট (COW) ডিভাইস। এটি যে কোনও আকারের হতে পারে, তবে বেস ডিভাইসের সমস্ত পরিবর্তনগুলি মিটমাট করার জন্য এটি অবশ্যই যথেষ্ট বড় হতে হবে।
  • snapshot টার্গেট ব্যবহার করে স্ন্যাপশট ডিভাইস তৈরি করা হয়। স্ন্যাপশট ডিভাইসে লেখাগুলি COW ডিভাইসে লেখা হয়। স্ন্যাপশট ডিভাইস থেকে পঠিত হয় বেস ডিভাইস বা COW ডিভাইস থেকে পড়া হয়, স্ন্যাপশট দ্বারা অ্যাক্সেস করা ডেটা পরিবর্তন করা হয়েছে কিনা তার উপর নির্ভর করে।
  • অরিজিন ডিভাইসটি snapshot-origin টার্গেট ব্যবহার করে তৈরি করা হয়েছে। বেস ডিভাইস থেকে সরাসরি অরিজিন ডিভাইসে পড়া হয়। অরিজিন ডিভাইসে লিখলে সরাসরি বেস ডিভাইসে লিখুন, কিন্তু COW ডিভাইসে লেখার মাধ্যমে আসল ডেটা ব্যাক আপ করা হয়।

Device mapping for dm-snapshot

চিত্র 2. ডিএম-স্ন্যাপশটের জন্য ডিভাইস ম্যাপিং

সংকুচিত স্ন্যাপশট

অ্যান্ড্রয়েড 12 এবং উচ্চতর, যেহেতু /data পার্টিশনে স্থানের প্রয়োজনীয়তা বেশি হতে পারে, আপনি /data পার্টিশনের উচ্চ স্থানের প্রয়োজনীয়তাগুলিকে মোকাবেলা করতে আপনার বিল্ডে সংকুচিত স্ন্যাপশটগুলি সক্ষম করতে পারেন।

ভার্চুয়াল A/B সংকুচিত স্ন্যাপশটগুলি Android 12 এবং উচ্চতর সংস্করণে উপলব্ধ নিম্নলিখিত উপাদানগুলির উপরে তৈরি করা হয়েছে:

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

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

সংকুচিত স্ন্যাপশটের জন্য COW বিন্যাস

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

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

সম্পূর্ণ OTA আপডেট শুধুমাত্র প্রতিস্থাপন এবং শূন্য অপারেশন নিয়ে গঠিত। ক্রমবর্ধমান OTA আপডেট অতিরিক্ত অনুলিপি অপারেশন থাকতে পারে.

অ্যান্ড্রয়েড 12-এ dm-ব্যবহারকারী

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

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

snapuserd

snapuserd dm-user স্ন্যাপসার্ড ইউজারস্পেস কম্পোনেন্ট ভার্চুয়াল A/B কম্প্রেশন প্রয়োগ করে।

ভার্চুয়াল A/B-এর আনকম্প্রেসড সংস্করণে, (হয় Android 11 এবং তার নিচের সংস্করণে, অথবা কম্প্রেসড স্ন্যাপশট বিকল্প ছাড়াই Android 12-এ), COW ডিভাইসটি একটি কাঁচা ফাইল। সংকোচন সক্রিয় করা হলে, COW একটি dm- dm-user ডিভাইস হিসাবে কাজ করে, যা snapuserd ডেমনের একটি উদাহরণের সাথে সংযুক্ত থাকে।

কার্নেল নতুন COW বিন্যাস ব্যবহার করে না। সুতরাং snapuserd উপাদানটি Android COW বিন্যাস এবং কার্নেলের অন্তর্নির্মিত বিন্যাসের মধ্যে অনুরোধগুলি অনুবাদ করে:

Snapuserd component translating requests between Android COW format and kernel built-in format

চিত্র 3. অ্যান্ড্রয়েড এবং কার্নেল COW ফর্ম্যাটের মধ্যে অনুবাদক হিসাবে স্ন্যাপসার্ডের ফ্লো ডায়াগ্রাম

এই অনুবাদ এবং ডিকম্প্রেশন ডিস্কে কখনই ঘটে না। snapuserd কম্পোনেন্ট কার্নেলে ঘটে যাওয়া COW পড়া এবং লিখতে বাধা দেয় এবং Android COW ফর্ম্যাট ব্যবহার করে প্রয়োগ করে।

XOR কম্প্রেশন

অ্যান্ড্রয়েড 13 এবং উচ্চতর ডিভাইসগুলির জন্য, XOR কম্প্রেশন বৈশিষ্ট্য, যা ডিফল্টরূপে সক্রিয় থাকে, পুরানো ব্লক এবং নতুন ব্লকগুলির মধ্যে XOR সংকুচিত বাইটগুলি সংরক্ষণ করতে ব্যবহারকারীর স্থান স্ন্যাপশটগুলিকে সক্ষম করে৷ যখন একটি ভার্চুয়াল A/B আপডেটে একটি ব্লকের মাত্র কয়েকটি বাইট পরিবর্তন করা হয়, তখন XOR কম্প্রেশন স্টোরেজ স্কিম ডিফল্ট স্টোরেজ স্কিমের চেয়ে কম জায়গা ব্যবহার করে কারণ স্ন্যাপশটগুলি সম্পূর্ণ 4K বাইট সংরক্ষণ করে না। স্ন্যাপশট আকারে এই হ্রাস করা সম্ভব কারণ XOR ডেটাতে অনেক শূন্য রয়েছে এবং কাঁচা ব্লক ডেটার চেয়ে সংকুচিত করা সহজ। Pixel ডিভাইসে, XOR কম্প্রেশন স্ন্যাপশটের আকার 25% থেকে 40% কমিয়ে দেয়।

অ্যান্ড্রয়েড 13 এবং উচ্চতর ডিভাইসে আপগ্রেড করার জন্য, XOR কম্প্রেশন সক্রিয় করা আবশ্যক। বিস্তারিত জানার জন্য, XOR কম্প্রেশন দেখুন।

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

এই বিভাগটি Android 13 এবং Android 12-এ ব্যবহৃত ভার্চুয়াল A/B কম্প্রেশন প্রক্রিয়া সম্পর্কে বিশদ প্রদান করে।

মেটাডেটা পড়া (Android 12)

মেটাডেটা একটি snapuserd ডেমন দ্বারা নির্মিত হয়। মেটাডেটা প্রাথমিকভাবে দুটি আইডির ম্যাপিং, প্রতিটি 8 বাইট, যা একত্রিত করা সেক্টরগুলিকে উপস্থাপন করে। dm-snapshot একে বলা হয় disk_exception

struct disk_exception {
    uint64_t old_chunk;
    uint64_t new_chunk;
};

একটি ডিস্ক ব্যতিক্রম ব্যবহার করা হয় যখন ডেটার একটি পুরানো অংশ একটি নতুন দ্বারা প্রতিস্থাপিত হয়।

একটি snapuserd ডেমন COW লাইব্রেরির মাধ্যমে অভ্যন্তরীণ COW ফাইলটি পড়ে এবং COW ফাইলে উপস্থিত প্রতিটি COW অপারেশনের জন্য মেটাডেটা তৈরি করে।

dm-snapshot dm- snapshot থেকে মেটাডেটা রিড শুরু করা হয়।

নীচের চিত্রটি মেটাডেটা নির্মাণের জন্য IO পাথের জন্য একটি ক্রম চিত্র প্রদান করে।

Sequence diagram, IO path for metadata construction

চিত্র 4. মেটাডেটা নির্মাণে IO পাথের জন্য ক্রম প্রবাহ

মার্জিং (Android 12)

বুট প্রক্রিয়া সম্পূর্ণ হলে, আপডেট ইঞ্জিন স্লটটিকে বুট সফল হিসাবে চিহ্নিত করে এবং dm-snapshot dm-snapshot-merge টার্গেটে স্যুইচ করে মার্জ শুরু করে।

dm-snapshot মেটাডেটার মধ্য দিয়ে চলে এবং প্রতিটি ডিস্ক ব্যতিক্রমের জন্য একটি মার্জ IO শুরু করে। মার্জ IO পাথের একটি উচ্চ-স্তরের ওভারভিউ নীচে দেখানো হয়েছে।

Merge IO path

চিত্র 5. IO পাথ ওভারভিউ মার্জ করুন

একত্রীকরণ প্রক্রিয়া চলাকালীন ডিভাইসটি পুনরায় বুট করা হলে, পরবর্তী রিবুটে মার্জ পুনরায় শুরু হবে এবং একত্রীকরণ সম্পন্ন হয়েছে।

ডিভাইস-ম্যাপার লেয়ারিং

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

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

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

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

চিত্র 6. ভার্চুয়াল A/B কম্প্রেশন প্রক্রিয়া

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

ইনইট ট্রানজিশন

কম্প্রেসড স্ন্যাপশট দিয়ে বুট করার সময়, পার্টিশন মাউন্ট করার জন্য প্রথম-পর্যায়ের init-কে অবশ্যই snapuserd শুরু করতে হবে। এটি একটি সমস্যা তৈরি করে: যখন sepolicy লোড করা হয় এবং প্রয়োগ করা হয়, তখন স্ন্যাপসার্ডকে ভুল প্রেক্ষাপটে রাখা হয় এবং snapuserd অস্বীকৃতি সহ এর পড়ার অনুরোধগুলি ব্যর্থ হয়।

এটি মোকাবেলা করার জন্য, snapuserd init এর সাথে লক-স্টেপে ট্রানজিশন করে, নিম্নরূপ:

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

স্থান ব্যবহার

নিম্নলিখিত টেবিলটি Pixel এর OS এবং OTA আকার ব্যবহার করে বিভিন্ন OTA প্রক্রিয়ার জন্য স্থান ব্যবহারের একটি তুলনা প্রদান করে।

আকারের প্রভাব অ-এ/বি A/B ভার্চুয়াল A/B ভার্চুয়াল A/B (সংকুচিত)
আসল কারখানার ছবি 4.5GB সুপার (3.8G ছবি + 700M সংরক্ষিত) 1 9GB সুপার (3.8G + 700M সংরক্ষিত, দুটি স্লটের জন্য) 4.5GB সুপার (3.8G ছবি + 700M সংরক্ষিত) 4.5GB সুপার (3.8G ছবি + 700M সংরক্ষিত)
অন্যান্য স্ট্যাটিক পার্টিশন /ক্যাশে কোনোটিই নয় কোনোটিই নয় কোনোটিই নয়
ওটিএ চলাকালীন অতিরিক্ত স্টোরেজ (ওটিএ প্রয়োগ করার পরে স্থান ফেরত দেওয়া হয়েছে) /ডেটাতে 1.4GB 0 3.8GB 2 অন/ডেটা 2.1GB 2 অন /ডেটা
OTA প্রয়োগ করতে মোট স্টোরেজ প্রয়োজন 5.9GB 3 (সুপার এবং ডেটা) 9GB (সুপার) 8.3GB 3 (সুপার এবং ডেটা) 6.6GB 3 (সুপার এবং ডেটা)

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

2 নতুন সিস্টেম ইমেজ মূল হিসাবে একই আকার অনুমান.

3 রিবুট না হওয়া পর্যন্ত স্থানের প্রয়োজন ক্ষণস্থায়ী।

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