ডায়নামিক পার্টিশন ছাড়া A/B ডিভাইসের জন্য OTA

অ্যান্ড্রয়েড ১০ ডাইনামিক পার্টিশন সমর্থন করে, যা একটি ইউজারস্পেস পার্টিশনিং সিস্টেম এবং এটি ওভার-দ্য-এয়ার (OTA) আপডেটের সময় পার্টিশন তৈরি, আকার পরিবর্তন এবং ধ্বংস করতে পারে।

এই পৃষ্ঠায় বর্ণনা করা হয়েছে, কীভাবে OTA ক্লায়েন্টরা ডাইনামিক পার্টিশন সাপোর্ট ছাড়া লঞ্চ হওয়া A/B ডিভাইসগুলোর আপডেটের সময় ডাইনামিক পার্টিশনের আকার পরিবর্তন করে এবং কীভাবে OTA ক্লায়েন্টরা অ্যান্ড্রয়েড ১০-এ আপগ্রেড করে।

পটভূমি

ডাইনামিক পার্টিশন সমর্থন করার জন্য একটি A/B ডিভাইস আপডেট করার সময়, ডিভাইসের GUID পার্টিশন টেবিল (GPT) সংরক্ষিত থাকে, তাই ডিভাইসে কোনো super পার্টিশন থাকে না। মেটাডেটা system_a এবং system_b তে সংরক্ষিত হয়, কিন্তু BOARD_SUPER_PARTITION_METADATA_DEVICE পরিবর্তন করে এটি কাস্টমাইজ করা যেতে পারে।

প্রতিটি ব্লক ডিভাইসে দুটি মেটাডেটা স্লট থাকে। প্রতিটি ব্লক ডিভাইসে কেবল একটি মেটাডেটা স্লট ব্যবহৃত হয়। উদাহরণস্বরূপ, system_a এর মেটাডেটা 0 এবং system_b এর মেটাডেটা 1 যথাক্রমে A এবং B স্লটের পার্টিশনগুলোকে নির্দেশ করে। রানটাইমে কোন স্লটটি আপডেট করা হচ্ছে, তা বিবেচ্য নয়।

এই পৃষ্ঠায়, মেটাডেটা স্লটগুলোকে মেটাডেটা S (সোর্স) এবং মেটাডেটা T (টার্গেট) বলা হয়। একইভাবে, পার্টিশনগুলোকে system_s , vendor_t ইত্যাদি নামে উল্লেখ করা হয়।

বিল্ড সিস্টেম কনফিগারেশন সম্পর্কে আরও তথ্যের জন্য, ডিভাইস আপগ্রেড করা দেখুন।

পার্টিশনগুলো কীভাবে আপডেট গ্রুপের অন্তর্ভুক্ত হয় সে সম্পর্কে আরও তথ্যের জন্য, নতুন ডিভাইসগুলোর জন্য বোর্ড কনফিগারেশন পরিবর্তন দেখুন।

ডিভাইসের মেটাডেটার একটি উদাহরণ হলো:

  • ভৌত ব্লক ডিভাইস system_a
    • মেটাডেটা ০
      • গ্রুপ foo_a
        • লজিক্যাল (ডাইনামিক) পার্টিশন system_a
        • লজিক্যাল (ডাইনামিক) পার্টিশন product_services_a
        • Foo দ্বারা অন্যান্য পার্টিশন আপডেট করা হয়েছে
      • গ্রুপ bar_a
        • লজিক্যাল (ডাইনামিক) পার্টিশন vendor_a
        • লজিক্যাল (ডাইনামিক) পার্টিশন product_a
        • বার দ্বারা অন্যান্য পার্টিশন আপডেট করা হয়েছে
    • মেটাডেটা ১ (ব্যবহৃত নয়)
  • ভৌত ব্লক ডিভাইস system_b
    • মেটাডেটা ০ (ব্যবহৃত নয়)
    • মেটাডেটা ১
      • গ্রুপ ফু_বি
        • লজিক্যাল (ডাইনামিক) পার্টিশন system_b
        • লজিক্যাল (ডাইনামিক) পার্টিশন product_services_b
        • Foo দ্বারা অন্যান্য পার্টিশন আপডেট করা হয়েছে
      • গ্রুপ বার_বি
        • লজিক্যাল (ডাইনামিক) পার্টিশন vendor_b
        • লজিক্যাল (ডাইনামিক) পার্টিশন product_b
        • বার দ্বারা অন্যান্য পার্টিশন আপডেট করা হয়েছে

আপনি আপনার ডিভাইসের মেটাডেটা ডাম্প করতে system/extras/partition_tools অধীনে থাকা lpdump টুলটি ব্যবহার করতে পারেন। উদাহরণস্বরূপ:

lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b

রেট্রোফিট একটি আপডেট

অ্যান্ড্রয়েড ৯ এবং এর পূর্ববর্তী সংস্করণ চালিত ডিভাইসগুলিতে, আপডেটের আগে ডিভাইসের OTA ক্লায়েন্ট ডাইনামিক পার্টিশন ম্যাপিং সমর্থন করে না। অতিরিক্ত এক সেট প্যাচ তৈরি করা হয়, যাতে ম্যাপিং সরাসরি বিদ্যমান ফিজিক্যাল পার্টিশনগুলিতে প্রয়োগ করা যায়।

OTA জেনারেটর চূড়ান্ত super.img ফাইলটি তৈরি করে, যেটিতে সমস্ত ডাইনামিক পার্টিশনের বিষয়বস্তু থাকে। এরপর এটি সিস্টেম, ভেন্ডর ইত্যাদির সাথে সম্পর্কিত ফিজিক্যাল ব্লক ডিভাইসগুলোর আকারের সাথে মিলিয়ে ইমেজটিকে একাধিক ইমেজে বিভক্ত করে। এই ইমেজগুলোর নাম দেওয়া হয় super_system.img , super_vendor.img ইত্যাদি। OTA ক্লায়েন্ট লজিক্যাল (ডাইনামিক) পার্টিশনের ইমেজগুলো প্রয়োগ না করে, এই ইমেজগুলোকেই ফিজিক্যাল পার্টিশনগুলোতে প্রয়োগ করে।

যেহেতু OTA ক্লায়েন্ট ডায়নামিক পার্টিশন ম্যাপ করতে জানে না, তাই আপডেট প্যাকেজ তৈরি করার সময় এই পার্টিশনগুলির জন্য সমস্ত পোস্ট-ইনস্টল ধাপ স্বয়ংক্রিয়ভাবে নিষ্ক্রিয় হয়ে যায়। আরও বিস্তারিত জানতে পোস্ট-ইনস্টলেশন কনফিগার করা দেখুন।

আপডেট প্রক্রিয়াটি অ্যান্ড্রয়েড ৯-এর মতোই।

আপডেটের আগে:

ro.boot.dynamic_partitions=
ro.boot.dynamic_partitions_retrofit=

আপডেটের পরে:

ro.boot.dynamic_partitions=true
ro.boot.dynamic_partitions_retrofit=true

রেট্রোফিটের পরে ভবিষ্যতের আপডেট

রেট্রোফিট আপডেটের পরে, OTA ক্লায়েন্টটি ডায়নামিক পার্টিশনের সাথে কাজ করার জন্য আপডেট করা হয়। সোর্স পার্টিশনের এক্সটেন্টগুলো কখনোই টার্গেট ফিজিক্যাল পার্টিশন জুড়ে বিস্তৃত হয় না।

নিয়মিত আপডেট প্যাকেজ ব্যবহার করে প্রবাহ আপডেট করুন

  1. super পার্টিশন মেটাডেটা প্রারম্ভিকীকরণ করুন।
    1. মেটাডেটা S (উৎস মেটাডেটা) থেকে নতুন মেটাডেটা M তৈরি করুন। উদাহরণস্বরূপ, যদি মেটাডেটা S ব্লক ডিভাইস হিসেবে [ system_s , vendor_s , product_s ] ব্যবহার করে, তাহলে নতুন মেটাডেটা M ব্লক ডিভাইস হিসেবে [ system_t , vendor_t , product_t ] ব্যবহার করবে। M-এ সমস্ত গ্রুপ এবং পার্টিশন বাতিল করা হয়।
    2. আপডেট ম্যানিফেস্টের dynamic_partition_metadata ফিল্ড অনুযায়ী টার্গেট গ্রুপ এবং পার্টিশন যোগ করুন। প্রতিটি পার্টিশনের আকার new_partition_info তে পাওয়া যাবে।
    3. মেটাডেটা T-তে M লিখুন।
    4. ডিভাইস ম্যাপারে যোগ করা পার্টিশনগুলোকে রাইটেবল হিসেবে ম্যাপ করুন।
  2. ব্লক ডিভাইসগুলোতে আপডেটটি প্রয়োগ করুন।
    1. প্রয়োজনে, ডিভাইস ম্যাপারে সোর্স পার্টিশনগুলোকে রিড-অনলি হিসেবে ম্যাপ করুন। সাইডলোডিংয়ের জন্য এটি প্রয়োজনীয়, কারণ আপডেটের আগে সোর্স পার্টিশনগুলো ম্যাপ করা থাকে না।
    2. টার্গেট স্লটের সমস্ত ব্লক ডিভাইসে একটি সম্পূর্ণ বা ডেল্টা আপডেট প্রয়োগ করুন।
    3. পোস্ট-ইনস্টল স্ক্রিপ্টটি চালানোর জন্য পার্টিশনগুলো মাউন্ট করুন এবং তারপর পার্টিশনগুলো আনমাউন্ট করুন।
  3. টার্গেট পার্টিশনগুলো আনম্যাপ করুন।

রেট্রোফিট আপডেট প্যাকেজ ব্যবহার করে আপডেট প্রবাহ

যদি রেট্রোফিট আপডেট প্যাকেজটি এমন কোনো ডিভাইসে প্রয়োগ করা হয় যেখানে আগে থেকেই ডাইনামিক পার্টিশন সক্রিয় করা আছে, তাহলে OTA ক্লায়েন্ট সরাসরি ব্লক ডিভাইসগুলিতে স্প্লিট super.img ফাইলটি প্রয়োগ করে। আপডেট প্রক্রিয়াটি একটি রেট্রোফিট আপডেটের মতোই। বিস্তারিত জানতে ‘Retrofitting an update’ দেখুন।

উদাহরণস্বরূপ, নিম্নলিখিত বিষয়গুলো ধরে নিন:

  • স্লট A হলো সক্রিয় স্লট।
  • system_a তে স্লট ০-এর সক্রিয় মেটাডেটা থাকে।
  • system_a , vendor_a , এবং product_a ব্লক ডিভাইস হিসেবে ব্যবহৃত হয়।

যখন OTA ক্লায়েন্ট একটি রেট্রোফিট আপডেট প্যাকেজ গ্রহণ করে, তখন এটি ফিজিক্যাল system_b তে super_system.img , ফিজিক্যাল vendor_b তে super_vendor.img এবং ফিজিক্যাল product_b তে super_product.img প্রয়োগ করে। ফিজিক্যাল ব্লক ডিভাইস system_b বুট করার সময় লজিক্যাল system_b , vendor_b এবং product_b ম্যাপ করার জন্য সঠিক মেটাডেটা থাকে।

আপডেট প্যাকেজ তৈরি করুন

ক্রমবর্ধমান OTA

রেট্রোফিট ডিভাইসগুলির জন্য ইনক্রিমেন্টাল OTA তৈরি করার সময়, আপডেটগুলি নির্ভর করে বেস বিল্ডে PRODUCT_USE_DYNAMIC_PARTITIONS এবং PRODUCT_RETROFIT_DYNAMIC_PARTITIONS সংজ্ঞায়িত আছে কি না তার উপর।

  • যদি বেস বিল্ডে ভেরিয়েবলগুলো সংজ্ঞায়িত না থাকে , তবে এটি একটি রেট্রোফিটিং আপডেট। আপডেট প্যাকেজটিতে স্প্লিট super.img ফাইলটি রয়েছে এবং এটি পোস্ট-ইনস্টল ধাপটি নিষ্ক্রিয় করে দেয়।
  • যদি বেস বিল্ডে ভেরিয়েবলগুলো সংজ্ঞায়িত করা থাকে , তবে এটি ডাইনামিক পার্টিশনসহ একটি সাধারণ আপডেটের মতোই। আপডেট প্যাকেজটিতে লজিক্যাল (ডাইনামিক) পার্টিশনের জন্য ইমেজগুলো থাকে। পোস্ট-ইনস্টল ধাপটি সক্রিয় করা যেতে পারে।

সম্পূর্ণ ওটিএ

রেট্রোফিট ডিভাইসগুলোর জন্য দুটি সম্পূর্ণ OTA প্যাকেজ তৈরি করা হয়।

  • $(PRODUCT)-ota-retrofit-$(TAG).zip ফাইলে সর্বদা বিভক্ত super.img থাকে এবং রেট্রোফিটিং আপডেটের জন্য পোস্ট-ইনস্টল ধাপটি নিষ্ক্রিয় করে।
    • এটি ota_from_target_files স্ক্রিপ্টে --retrofit_dynamic_partitions নামক একটি অতিরিক্ত আর্গুমেন্ট যোগ করে তৈরি করা হয়।
    • এটি সকল বিল্ডে প্রয়োগ করা যেতে পারে।
  • $(PRODUCT)-ota-$(TAG).zip ভবিষ্যৎ আপডেটের জন্য লজিক্যাল ইমেজ রয়েছে।
    • এটি শুধুমাত্র ডাইনামিক পার্টিশন সক্রিয় থাকা বিল্ডগুলিতে প্রয়োগ করুন। এটি কার্যকর করার বিষয়ে বিস্তারিত নিচে দেখুন।

পুরানো বিল্ডগুলিতে ননরেট্রোফিট আপডেট প্রত্যাখ্যান করুন

নিয়মিত সম্পূর্ণ OTA প্যাকেজটি শুধুমাত্র ডাইনামিক পার্টিশন সক্রিয় থাকা বিল্ডগুলিতে প্রয়োগ করুন। যদি OTA সার্ভারটি ভুলভাবে কনফিগার করা থাকে এবং Android 9 বা তার নিচের সংস্করণে চালিত ডিভাইসগুলিতে এই প্যাকেজগুলি পাঠায়, তাহলে ডিভাইসগুলি বুট হতে ব্যর্থ হয়। Android 9 এবং তার নিচের সংস্করণের OTA ক্লায়েন্ট একটি রেট্রোফিট OTA প্যাকেজ এবং একটি নিয়মিত সম্পূর্ণ OTA প্যাকেজের মধ্যে পার্থক্য করতে পারে না, তাই ক্লায়েন্টটি সম্পূর্ণ প্যাকেজটি প্রত্যাখ্যান করবে না।

ডিভাইসটি যাতে সম্পূর্ণ OTA প্যাকেজ গ্রহণ না করে, সেজন্য আপনি বিদ্যমান ডিভাইস কনফিগারেশন পরীক্ষা করার জন্য একটি পোস্ট-ইনস্টল ধাপ বাধ্যতামূলক করতে পারেন। উদাহরণস্বরূপ:

device/ device_name /dynamic_partitions/check_dynamic_partitions

#!/system/bin/sh
DP_PROPERTY_NAME="ro.boot.dynamic_partitions"
DP_RETROFIT_PROPERTY_NAME="ro.boot.dynamic_partitions_retrofit"

DP_PROPERTY=$(getprop ${DP_PROPERTY_NAME})
DP_RETROFIT_PROPERTY=$(getprop ${DP_RETROFIT_PROPERTY_NAME})

if [ "${DP_PROPERTY}" != "true" ] || [ "${DP_RETROFIT_PROPERTY}" != "true" ] ; then
    echo "Error: applied non-retrofit update on build without dynamic" \
         "partitions."
    echo "${DP_PROPERTY_NAME}=${DP_PROPERTY}"
    echo "${DP_RETROFIT_PROPERTY_NAME}=${DP_RETROFIT_PROPERTY}"
    exit 1
fi

device/ device_name /dynamic_partitions/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= check_dynamic_partitions
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_SRC_FILES := check_dynamic_partitions
LOCAL_PRODUCT_MODULE := true
include $(BUILD_PREBUILT)

device/ device_name /device.mk

PRODUCT_PACKAGES += check_dynamic_partitions

# OPTIONAL=false so that the error in check_dynamic_partitions will be
# propagated to OTA client.
AB_OTA_POSTINSTALL_CONFIG += \
    RUN_POSTINSTALL_product=true \
    POSTINSTALL_PATH_product=bin/check_dynamic_partitions \
    FILESYSTEM_TYPE_product=ext4 \
    POSTINSTALL_OPTIONAL_product=false \

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