Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Ikhtisar A/B Virtual

Android memiliki dua mekanisme pembaruan: pembaruan A/B (mulus) dan pembaruan non-A/B. Untuk mengurangi kerumitan kode dan menyempurnakan proses pembaruan, di Android 11 kedua mekanisme tersebut disatukan melalui A/B virtual untuk menghadirkan pembaruan tanpa hambatan ke semua perangkat dengan biaya penyimpanan yang diminimalkan. Android 12 menawarkan opsi kompresi A/B Virtual untuk mengompresi partisi yang di-snapshot. Di Android 11 dan Android 12, hal berikut ini berlaku:

  • Virtual update A / B yang mulus seperti update A / B. Pembaruan A/B virtual meminimalkan waktu perangkat offline dan tidak dapat digunakan.
  • Virtual update A / B dapat diperpanjang kembali. Jika OS baru gagal untuk boot, perangkat secara otomatis memutar kembali ke versi sebelumnya.
  • Virtual update A / B menggunakan minimal ruang ekstra dengan menduplikasi hanya partisi yang digunakan oleh bootloader. Partisi diupdate lainnya snapshotted .

Latar belakang dan terminologi

Bagian ini mendefinisikan terminologi dan menjelaskan teknologi yang mendukung A/B virtual.

Pemeta perangkat

Device-mapper adalah lapisan blok virtual Linux yang sering digunakan di Android. Dengan partisi dinamis , partisi seperti /system adalah tumpukan perangkat berlapis:

  • Di bagian bawah tumpukan adalah partisi yang super fisik (misalnya, /dev/block/by-name/super ).
  • Di tengah adalah sebuah dm-linear perangkat, menentukan yang blok dalam bentuk partisi yang super partisi yang diberikan. Muncul ini sebagai /dev/block/mapper/system_[a|b] pada perangkat A / B, atau /dev/block/mapper/system pada / perangkat non-A B.
  • Di bagian atas berada dalam dm-verity perangkat, diciptakan untuk partisi diverifikasi. Perangkat ini memverifikasi bahwa blok pada dm-linear perangkat ditandatangani dengan benar. Ini muncul sebagai /dev/block/mapper/system-verity dan merupakan sumber dari /system mount point.

Gambar 1 menunjukkan apa yang stack di bawah /system mount point terlihat seperti.

Partition stacking underneath system

Gambar 1. Stack bawah / sistem mount point

dm-snapshot

Virtual A / B bergantung pada dm-snapshot , modul perangkat-mapper untuk snapshotting keadaan perangkat penyimpanan. Bila menggunakan dm-snapshot , ada empat perangkat dalam bermain:

  • Perangkat dasar adalah perangkat yang snapshotted. Pada halaman ini, perangkat dasar selalu merupakan partisi dinamis, seperti sistem atau vendor.
  • Copy-on-write (KK) perangkat, untuk penebangan perubahan pada perangkat dasar. Ukurannya bisa berapa saja, tetapi harus cukup besar untuk mengakomodasi semua perubahan pada perangkat dasar.
  • Perangkat snapshot dibuat menggunakan snapshot sasaran. Menulis ke perangkat snapshot ditulis ke perangkat COW. Membaca dari perangkat snapshot membaca baik dari perangkat dasar atau perangkat COW, tergantung pada apakah data yang diakses telah diubah oleh snapshot.
  • Perangkat asal dibuat menggunakan snapshot-origin sasaran. Membaca ke perangkat asal membaca langsung dari perangkat dasar. Menulis ke perangkat asal menulis langsung ke perangkat dasar, tetapi data asli dicadangkan dengan menulis ke perangkat COW.

Device mapping for dm-snapshot

Gambar 2. Perangkat pemetaan untuk dm-snapshot

Snapshot terkompresi

Di Android 12, karena kebutuhan ruang pada /data partisi bisa tinggi, Anda dapat mengaktifkan dikompresi snapshot dalam membangun Anda untuk mengatasi kebutuhan ruang yang lebih tinggi dari /data partisi.

Snapshot terkompresi A/B virtual dibuat di atas dua komponen baru yang tersedia di Android 12:

  • dm-user , modul kernel mirip dengan FUSE yang memungkinkan userspace untuk melaksanakan perangkat blok.
  • snapuserd , daemon userspace untuk menerapkan format snapshot baru.

Komponen-komponen ini memungkinkan kompresi. Perubahan yang diperlukan lain yang dibuat untuk melaksanakan snapshot dikompresi kemampuan diberikan dalam bagian berikutnya: Format KK untuk snapshot dikompresi , dm-pengguna , dan Snapuserd .

Format COW untuk snapshot terkompresi

Di Android 12, snapshot terkompresi menggunakan format COW baru. Mirip dengan format bawaan kernel yang digunakan untuk snapshot yang tidak terkompresi, format COW untuk snapshot terkompresi memiliki bagian metadata dan data yang bergantian. Metadata format asli hanya diperbolehkan untuk "mengganti" operasi: Ganti blok X di dasar gambar dengan isi blok Y di foto itu. Format COW snapshot terkompresi lebih ekspresif dan mendukung tiga operasi:

  • Salin - Blok X di perangkat dasar harus diganti dengan blok Y di perangkat dasar.
  • Ganti - Blok X di perangkat dasar harus diganti dengan isi blok Y di foto itu. Masing-masing blok ini dikompresi gz.
  • Nol - Blok X di perangkat dasar harus diganti dengan semua nol.

Update penuh OTA terdiri dari mengganti dan nol operasi saja. Incremental update OTA juga dapat memiliki operasi copy.

dm-pengguna di Android 12

Modul kernel dm-pengguna memungkinkan userspace untuk menerapkan perangkat block device-mapper. Sebuah entri tabel dm-pengguna membuat perangkat aneka bawah /dev/dm-user/<control-name> . Sebuah userspace proses dapat polling perangkat untuk menerima membaca dan menulis permintaan dari kernel. Setiap permintaan memiliki buffer terkait untuk ruang pengguna untuk diisi (untuk membaca) atau menyebar (untuk menulis).

The dm-user modul kernel menyediakan antarmuka dapat dilihat pengguna baru ke kernel yang bukan merupakan bagian dari basis kode kernel.org hulu. Sampai itu, Google berhak untuk memodifikasi dm-user antarmuka di Android.

pengguna snap

The snapuserd komponen userspace ke dm-user mengimplementasikan virtual A / B Kompresi.

Dalam versi Virtual A/B yang tidak terkompresi, (baik di Android 11 dan yang lebih rendah, atau di Android 12 tanpa opsi snapshot terkompresi), perangkat COW adalah file mentah. Bila kompresi diaktifkan, fungsi KK bukan sebagai dm-user perangkat, yang terhubung ke sebuah contoh dari snapuserd daemon.

Kernel tidak menggunakan format COW baru. Jadi snapuserd komponen menerjemahkan permintaan antara format KK Android dan kernel dibangun-dalam format:

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

Diagram Gambar 3. Arus dari snapuserd sebagai penerjemah antara Android dan Kernel format KK

Terjemahan dan dekompresi ini tidak pernah terjadi pada disk. The snapuserd penyadapan komponen KK membaca dan menulis yang terjadi di kernel, dan menerapkan mereka menggunakan format KK Android.

Proses kompresi A/B virtual

Bagian ini memberikan detail mengenai proses yang digunakan dalam kompresi A/B Virtual: membaca metadata, menggabungkan, dan melakukan transisi init.

Membaca metadata

Metadata dibangun oleh snapuserd daemon. Metadata utamanya adalah pemetaan 2 ID, masing-masing 8 byte, yang mewakili sektor yang akan digabungkan. Dalam dm-snapshot itu disebut sebagai disk_exception .

struct disk_exception {
    uint64_t old_chunk;
    uint64_t new_chunk;
};

Pengecualian disk digunakan ketika sepotong data lama diganti dengan yang baru.

Sebuah Snapuserd daemon membaca file KK internal melalui perpustakaan KK dan membangun metadata untuk masing-masing hadir operasi KK dalam file KK.

Metadata membaca diawali dari dm-snapshot di kernel ketika dm- snapshot perangkat dibuat.

Gambar di bawah memberikan diagram urutan untuk jalur IO untuk konstruksi metadata.

Sequence diagram, IO path for metadata construction

Gambar 4. aliran Urutan untuk jalur IO dalam konstruksi metadata

Penggabungan

Setelah proses booting selesai, tanda pembaruan mesin slot sebagai boot sukses dan inisiat penggabungan dengan beralih dm-snapshot sasaran ke dm-snapshot-merge sasaran.

dm-snapshot berjalan melalui metadata dan memulai gabungan IO untuk setiap pengecualian disk. Ikhtisar tingkat tinggi dari jalur gabungan IO ditunjukkan di bawah ini.

Merge IO path

Gambar 5. Gabung gambaran IO jalan

Jika perangkat di-boot ulang selama proses penggabungan, penggabungan dilanjutkan pada reboot berikutnya, dan penggabungan selesai.

Init transisi

Ketika booting dengan snapshot dikompresi, init tahap pertama harus mulai snapuserd untuk me-mount partisi. Ini pose masalah: Ketika sepolicy dimuat dan ditegakkan, snapuserd akan dimasukkan dalam konteks yang salah, dan permintaan membaca nya gagal, dengan penolakan selinux.

Untuk mengatasi ini, snapuserd transisi di lock-langkah dengan init , sebagai berikut:

  1. Tahap pertama init peluncuran snapuserd dari ramdisk, dan menyimpan terbuka file descriptor untuk itu dalam variabel lingkungan.
  2. Tahap pertama init switch root filesystem ke partisi sistem, kemudian mengeksekusi salinan sistem init .
  3. Sistem salinan init membaca sepolicy gabungan ke dalam string.
  4. Init memanggil mlock() halaman pada semua ext4 didukung. Kemudian menonaktifkan semua tabel perangkat-mapper untuk perangkat snapshot, dan berhenti snapuserd . Setelah ini dilarang membaca dari partisi, karena hal itu menyebabkan kebuntuan.
  5. Menggunakan descriptor terbuka untuk copy ramdisk dari snapuserd , init relaunches daemon dengan konteks selinux yang benar. Tabel device-mapper untuk perangkat snapshot diaktifkan kembali.
  6. Memanggil init munlockall() - itu aman untuk melakukan IO lagi.

Penggunaan ruang

Tabel berikut memberikan perbandingan penggunaan ruang untuk mekanisme OTA yang berbeda menggunakan OS Pixel dan ukuran OTA.

Dampak Ukuran non-A/B A/B Virtual A/B Virtual A/B (terkompresi)
Gambar Pabrik Asli 4.5GB super (image 3.8g + 700 dicadangkan) 1 9GB super (3.8G + 700M dicadangkan, untuk dua slot) 4.5GB super (gambar 3.8G + 700 juta dicadangkan) 4.5GB super (gambar 3.8G + 700 juta dicadangkan)
Partisi statis lainnya /cache Tidak ada Tidak ada Tidak ada
Penyimpanan tambahan Selama OTA (ruang kembali setelah menerapkan OTA) 1.4GB di /data 0 3.8GB 2 on / Data 2.1GB 2 on / Data
Total penyimpanan yang diperlukan untuk menerapkan OTA 5.9GB 3 (super dan data) 9GB (super) 8.3GB 3 (super dan data) 6.6GB 3 (super dan data)

1 Menunjukkan tata letak diasumsikan berdasarkan pemetaan Pixel.

2 Menganggap gambar sistem baru adalah ukuran yang sama seperti aslinya.

3 persyaratan Space sementara sampai reboot.

Untuk menerapkan Virtual A / B, atau menggunakan kemampuan snapshot dikompresi, lihat Menerapkan Virtual A / B