Android 10 में यूज़र डेटा चेकपॉइंट (यूडीसी) की सुविधा जोड़ी गई है. इसकी मदद से, Android को पिछली स्थिति में वापस लाया जा सकता है. ऐसा तब होता है, जब Android का ओवर-द-एयर (ओटीए) अपडेट पूरा नहीं हो पाता. यूडीसी की मदद से, Android के ओटीए अपडेट के फ़ेल होने पर, डिवाइस को सुरक्षित तरीके से उसकी पिछली स्थिति में वापस लाया जा सकता है. हालांकि, A/B अपडेट से बूटिंग की शुरुआती प्रोसेस में होने वाली इस समस्या को हल किया जा सकता है. हालांकि, जब उपयोगकर्ता के डेटा वाले पार्टीशन (/data
पर माउंट किया गया) में बदलाव किया जाता है, तब रोलबैक की सुविधा काम नहीं करती.
यूडीसी की मदद से, डिवाइस में उपयोगकर्ता के डेटा के पार्टीशन को बदला जा सकता है. यूडीसी सुविधा, फ़ाइल सिस्टम के लिए चेकपॉइंट की सुविधाओं के साथ ऐसा करती है. साथ ही, जब फ़ाइल सिस्टम चेकपॉइंट की सुविधा के साथ काम नहीं करता है, तो यह सुविधा एक वैकल्पिक तरीके से काम करती है. यह बूटलोडर A/B मेकेनिज़्म के साथ इंटिग्रेट होती है. साथ ही, यह नॉन-A/B अपडेट के साथ भी काम करती है. इसके अलावा, यह मुख्य वर्शन बाइंडिंग और मुख्य रोलबैक को रोकने की सुविधा के साथ भी काम करती है.
उपयोगकर्ता पर असर
यूडीसी की सुविधा से, उपयोगकर्ताओं को ओटीए अपडेट का बेहतर अनुभव मिलता है. ऐसा इसलिए, क्योंकि ओटीए अपडेट के फ़ेल होने पर कम उपयोगकर्ताओं का डेटा मिटता है. इससे, अपडेट की प्रोसेस के दौरान समस्याओं का सामना करने वाले लोगों से मिलने वाले सहायता कॉल की संख्या कम हो सकती है. हालांकि, ओटीए अपडेट के काम न करने पर, उपयोगकर्ताओं को डिवाइस के कई बार रीबूट होने की समस्या दिख सकती है.
यह कैसे काम करता है
अलग-अलग फ़ाइल सिस्टम में चेकपॉइंट की सुविधा
F2FS फ़ाइल सिस्टम के लिए, यूडीसी ने अपस्ट्रीम 4.20 Linux कर्नेल में चेकपॉइंट की सुविधा जोड़ी है. साथ ही, इसे Android 10 पर काम करने वाले डिवाइसों के साथ काम करने वाले सभी सामान्य कर्नेल में बैकपोर्ट किया है.
अन्य फ़ाइल सिस्टम के लिए, यूडीसी एक डिवाइस मैपर वर्चुअल डिवाइस का इस्तेमाल करता है. इसे dm_bow
कहा जाता है. इसका इस्तेमाल चेकपॉइंट फ़ंक्शन के लिए किया जाता है. dm_bow
, डिवाइस और फ़ाइल सिस्टम के बीच होता है. जब किसी पार्टीशन को माउंट किया जाता है, तो ट्रिम कमांड जारी की जाती है. इससे फ़ाइल सिस्टम, सभी खाली ब्लॉक पर ट्रिम कमांड जारी करता है. dm_bow
इन ट्रिम को इंटरसेप्ट करता है और इनका इस्तेमाल, मुफ़्त में ब्लॉक की गई सूची को सेट अप करने के लिए करता है. इसके बाद, पढ़े और लिखे गए डेटा को डिवाइस पर बिना किसी बदलाव के भेज दिया जाता है. हालांकि, डेटा को लिखने की अनुमति देने से पहले, वापस लाने के लिए ज़रूरी डेटा को किसी खाली ब्लॉक में बैक अप ले लिया जाता है.
चेकपॉइंट की प्रोसेस
checkpoint=fs/block
फ़्लैग वाले किसी पार्टीशन को माउंट करने पर, Android ड्राइव पर restoreCheckpoint
को कॉल करता है, ताकि डिवाइस मौजूदा चेकपॉइंट को वापस ला सके. इसके बाद, init
, needsCheckpoint
फ़ंक्शन को कॉल करता है. इससे यह पता चलता है कि डिवाइस, बूटलोडर A/B स्टेट में है या उसने अपडेट को फिर से आज़माने की संख्या सेट की है. इनमें से किसी भी शर्त के पूरा होने पर, Android createCheckpoint
को कॉल करता है. इससे माउंट फ़्लैग जोड़े जा सकते हैं या dm_bow
डिवाइस बनाया जा सकता है.
पार्टिशन माउंट होने के बाद, ट्रिम जारी करने के लिए चेकपॉइंट कोड को कॉल किया जाता है.
इसके बाद, बूट प्रोसेस सामान्य तरीके से जारी रहती है. LOCKED_BOOT_COMPLETE
पर, Android commitCheckpoint
को कॉल करता है, ताकि मौजूदा चेकपॉइंट को सेव किया जा सके. इसके बाद, अपडेट सामान्य तरीके से जारी रहता है.
KeyMint (पहले Keymaster) कुंजियां मैनेज करना
KeyMint कुंजियों का इस्तेमाल, डिवाइस को एन्क्रिप्ट (सुरक्षित) करने या अन्य कामों के लिए किया जाता है. इन कुंजियों को मैनेज करने के लिए, Android, कुंजी मिटाने के अनुरोधों को तब तक के लिए रोक देता है, जब तक कि चेकपॉइंट कमिट नहीं हो जाता.
सेहत की निगरानी करना
हेल्थ डेमॉन यह पुष्टि करता है कि चेकपॉइंट बनाने के लिए, डिस्क में ज़रूरत के मुताबिक जगह खाली है. सेहत से जुड़ा डेमॉन, Checkpoint.cpp
में cp_healthDaemon
में मौजूद होता है.
हेल्थ डेमॉन के ये व्यवहार कॉन्फ़िगर किए जा सकते हैं:
ro.sys.cp_msleeptime
: इससे यह कंट्रोल किया जाता है कि डिवाइस, डिस्क के इस्तेमाल की जांच कितनी बार करे.ro.sys.cp_min_free_bytes
: इससे यह तय होता है कि हेल्थ डेमॉन, कम से कम कितनी वैल्यू खोजेगा.ro.sys.cp_commit_on_full
: इससे यह कंट्रोल किया जाता है कि डिस्क पूरी तरह से भर जाने पर, हेल्थ डेमॉन डिवाइस को रीबूट करेगा या चेकपॉइंट को कमिट करेगा और काम जारी रखेगा.
Checkpoint APIs
चेकपॉइंट एपीआई का इस्तेमाल, यूडीसी सुविधा करती है. यूडीसी के साथ इस्तेमाल किए जाने वाले अन्य एपीआई के बारे में जानने के लिए, IVold.aidl
देखें.
void startCheckpoint(int retry)
चेकपॉइंट बनाता है.
अपडेट शुरू करने के लिए तैयार होने पर, फ़्रेमवर्क इस तरीके को कॉल करता है. यह चेकपॉइंट, चेकपॉइंट किए गए फ़ाइल सिस्टम से पहले बनाया जाता है. जैसे, रीबूट करने के बाद userdata को R/W के तौर पर माउंट किया जाता है. अगर फिर से कोशिश करने की संख्या पॉज़िटिव है, तो एपीआई ट्रैकिंग की फिर से कोशिश करने की प्रोसेस को मैनेज करता है. साथ ही, अपडेटर needsRollback
को कॉल करके यह देखता है कि अपडेट को रोलबैक करने की ज़रूरत है या नहीं. अगर फिर से कोशिश करने की संख्या -1
है, तो एपीआई, A/B बूटलोडर के फ़ैसले को मानता है.
सामान्य A/B अपडेट करते समय, इस तरीके को कॉल नहीं किया जाता.
void commitChanges()
बदलावों को सेव करता है.
बदलावों को लागू करने के लिए तैयार होने पर, रीबूट के बाद फ़्रेमवर्क इस तरीके को कॉल करता है. इसे userdata में डेटा (जैसे कि तस्वीरें, वीडियो, एसएमएस, सर्वर से मिला डेटा) लिखे जाने से पहले और BootComplete
से पहले कॉल किया जाता है.
अगर कोई चालू चेकपॉइंट अपडेट मौजूद नहीं है, तो इस तरीके का कोई असर नहीं होता.
abortChanges()
इससे डिवाइस रीबूट हो जाता है और चेकपॉइंट पर वापस आ जाता है. पहले रीबूट के बाद से, उपयोगकर्ता के डेटा में किए गए सभी बदलावों को खारिज कर देता है.
फ़्रेमवर्क, इस तरीके को रीबूट के बाद कॉल करता है, लेकिन commitChanges
से पहले.
इस तरीके को कॉल करने पर, retry_counter
की वैल्यू कम हो जाती है. लॉग एंट्री जनरेट की जाती हैं.
bool needsRollback()
यह कुकी तय करती है कि रोलबैक करना ज़रूरी है या नहीं.
बिना चेकपॉइंट वाले डिवाइसों पर, false
दिखाता है. चेकपॉइंट डिवाइसों पर, नॉनचेकपॉइंट बूट के दौरान true
दिखाता है.
यूडीसी लागू करना
रेफ़रंस के तौर पर लागू करना
यूडीसी को लागू करने के तरीके का उदाहरण देखने के लिए, dm-bow.c देखें. इस सुविधा के बारे में ज़्यादा जानकारी के लिए, dm-bow.txt देखें.
सेटअप
अपनी init.hardware.rc
फ़ाइल में मौजूद on fs
में, पक्का करें कि आपके पास ये चीज़ें हों:
mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --early
अपनी init.hardware.rc
फ़ाइल में मौजूद on late-fs
में, पक्का करें कि आपके पास ये चीज़ें हों:
mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late
अपनी fstab.hardware
फ़ाइल में, पक्का करें कि /data
को latemount
के तौर पर टैग किया गया हो.
/dev/block/bootdevice/by-name/userdata /data f2fs noatime,nosuid,nodev,discard,reserve_root=32768,resgid=1065,fsync_mode=nobarrier latemount,wait,check,fileencryption=ice,keydirectory=/metadata/vold/metadata_encryption,quota,formattable,sysfs_path=/sys/devices/platform/soc/1d84000.ufshc,reservedsize=128M,checkpoint=fs
मेटाडेटा पार्टीशन जोड़ना
UDC को नॉनबूटलोडर रीट्राय की संख्या और कुंजियों को सेव करने के लिए, मेटाडेटा पार्टिशन की ज़रूरत होती है. मेटाडेटा पार्टिशन सेट अप करें और उसे /metadata
पर जल्दी माउंट करें.
अपनी fstab.hardware
फ़ाइल में, पक्का करें कि /metadata
को earlymount
या first_stage_mount
के तौर पर टैग किया गया हो.
/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount
पार्टिशन को सभी शून्य पर सेट करें.
BoardConfig.mk
में ये लाइनें जोड़ें:
BOARD_USES_METADATA_PARTITION := true BOARD_ROOT_EXTRA_FOLDERS := existing_folders metadata
सिस्टम अपडेट करना
F2FS सिस्टम
डेटा को फ़ॉर्मैट करने के लिए F2FS का इस्तेमाल करने वाले सिस्टम के लिए, पक्का करें कि आपके F2FS के वर्शन में चेकपॉइंट की सुविधा काम करती हो. ज़्यादा जानकारी के लिए, अलग-अलग फ़ाइल सिस्टम में चेकपॉइंट की सुविधा देखें.
/data
पर माउंट किए गए डिवाइस के लिए, fstab के <fs_mgr_flags>
सेक्शन में checkpoint=fs
फ़्लैग जोड़ें.
F2FS के अलावा अन्य सिस्टम
F2FS के अलावा अन्य फ़ाइल सिस्टम के लिए, कर्नेल कॉन्फ़िगरेशन में dm-bow
चालू होना चाहिए.
/data
पर माउंट किए गए डिवाइस के लिए, fstab के <fs_mgr_flags>
सेक्शन में checkpoint=block
फ़्लैग जोड़ें.
लॉग देखना
जब Checkpoint API को कॉल किया जाता है, तब लॉग एंट्री जनरेट होती हैं.
Validation
यूडीसी लागू करने की जांच करने के लिए, VtsKernelCheckpointTest
वीटीएस टेस्ट का सेट चलाएं.