Ringkasan A/B virtual

Android memiliki dua mekanisme update: update A/B (mulus) dan update non-A/B. Untuk mengurangi kompleksitas kode dan meningkatkan proses update, di Android 11 dua mekanisme disatukan melalui A/B virtual untuk memberikan pembaruan yang lancar bagi semua perangkat dengan biaya penyimpanan yang minimal. Android 12 menawarkan opsi kompresi A/B Virtual untuk partisi yang dikompresi. Di Android 11 dan Android 12, hal berikut terapkan:

  • Update A/B virtual mulus seperti update A/B. Update A/B virtual meminimalkan waktu perangkat offline dan tidak dapat digunakan.
  • Update A/B virtual dapat di-roll back. Jika OS baru gagal {i>booting<i}, perangkat akan melakukan roll back secara otomatis ke versi sebelumnya.
  • Update A/B virtual menggunakan ruang minimum tambahan dengan hanya menduplikasi partisi yang digunakan oleh {i>bootloader<i}. Partisi lainnya yang dapat diperbarui adalah di-snapshot.

Latar Belakang dan terminologi

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

Peta 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 terdapat partisi super fisik (misalnya, /dev/block/by-name/super).
  • Di tengah terdapat perangkat dm-linear, yang menentukan blok mana di bagian super partisi dari partisi yang diberikan. Hal ini ditampilkan sebagai /dev/block/mapper/system_[a|b] di perangkat A/B, atau /dev/block/mapper/system pada perangkat non-A/B.
  • Di bagian atas terdapat perangkat dm-verity, yang dibuat untuk partisi terverifikasi. Perangkat ini memverifikasi bahwa pemblokiran di perangkat dm-linear telah ditandatangani dengan benar. ID tersebut muncul sebagai /dev/block/mapper/system-verity dan merupakan sumber dari titik pemasangan /system.

Gambar 1 menunjukkan tampilan stack di bawah direktori pemasangan /system.

Partisi menumpuk di bawahnya
sistem

Gambar 1. Tumpuk di bawah titik pemasangan /system

ringkasan dm

A/B Virtual bergantung pada dm-snapshot, sebuah modul mapper perangkat untuk pengambilan snapshot perangkat penyimpanan. Saat menggunakan dm-snapshot, ada empat perangkat di putar:

  • Perangkat dasar adalah perangkat yang diambil snapshot-nya. Pada halaman ini, dasar adalah partisi dinamis, seperti sistem atau vendor.
  • Perangkat copy-on-write (COW), untuk mencatat perubahan pada perangkat dasar. Ini dapat berukuran berapa saja, tetapi harus cukup besar untuk mengakomodasi semua perubahan perangkat dasar.
  • Perangkat snapshot dibuat menggunakan target snapshot. Menulis ke perangkat snapshot ditulis ke perangkat COW. Membaca dari snapshot dibaca dari perangkat dasar atau perangkat COW, tergantung pada apakah data yang sedang diakses telah diubah oleh {i>snapshot<i}.
  • Perangkat origin dibuat menggunakan target snapshot-origin. Membaca ke perangkat asal yang dibaca langsung dari perangkat dasar. Menulis ke origin menulis langsung ke perangkat dasar, tetapi data aslinya dicadangkan dengan menulis ke perangkat COW.

Pemetaan perangkat untuk
ringkasan dm

Gambar 2. Pemetaan perangkat untuk snapshot dm

Snapshot terkompresi

Di Android 12 dan yang lebih tinggi, karena persyaratan ruang pada ukuran partisi /data bisa jadi tinggi, Anda dapat mengaktifkan snapshot terkompresi di build untuk mengatasi persyaratan ruang yang lebih tinggi dari partisi /data.

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

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

Komponen-komponen ini mengaktifkan kompresi. Perubahan lain yang diperlukan yang dibuat pada kemampuan mengimplementasikan snapshot terkompresi akan dijelaskan di bagian selanjutnya: Format COW untuk snapshot terkompresi, dm-user, dan Snapuserd.

Format COW untuk snapshot terkompresi

Di Android 12 dan yang lebih tinggi, snapshot terkompresi menggunakan dalam format COW. Mirip dengan format {i>built-in<i} {i>kernel<i} yang digunakan untuk maka format COW untuk snapshot terkompresi memiliki bagian alternatif {i>metadata<i} dan data. Metadata format asli yang diizinkan hanya untuk ganti operasi: Ganti blok X di image dasar dengan konten blok Y dalam snapshot. Format COW snapshot terkompresi lebih ekspresif dan mendukung operasi berikut:

  • Salin: Blok X di perangkat dasar harus diganti dengan blok Y di perangkat dasar.
  • Ganti: Blok X di perangkat dasar harus diganti dengan konten blok Y dalam snapshot. Masing-masing blok ini dikompresi gz.
  • Nol: Blok X di perangkat dasar harus diganti dengan semua angka nol.
  • XOR: Perangkat COW menyimpan byte terkompresi XOR antara blok X dan blok Y. (Tersedia di Android 13 dan yang lebih baru.)

Update OTA lengkap hanya terdiri dari operasi replace dan zero. Inkremental Update OTA juga dapat memiliki operasi salinan.

dm-user di Android 12

Modul kernel pengguna dm memungkinkan userspace menerapkan blok mapper perangkat perangkat. Entri tabel pengguna {i>dm<i} membuat perangkat lain di bawah /dev/dm-user/<control-name>. Proses userspace dapat melakukan polling di perangkat menerima permintaan baca dan tulis dari {i>kernel<i}. Setiap permintaan memiliki konteks buffer bagi userspace untuk mengisi (untuk pembacaan) atau menyebarkan (untuk penulisan).

Modul kernel dm-user menyediakan antarmuka baru yang terlihat oleh pengguna ke kernel yang bukan bagian dari {i> code base<i} upstream {i>kernel.org<i}. Sampai saat ini, Google berhak memodifikasi antarmuka dm-user di Android.

{i>snapuserd<i}

Komponen userspace snapuserd untuk dm-user menerapkan A/B Virtual kompresi data.

Dalam versi A/B Virtual yang tidak dikompresi (baik di Android 11 dan yang lebih rendah, atau di Android 12 tanpa opsi snapshot terkompresi), perangkat COW adalah file mentah. Saat kompresi diaktifkan, fungsi COW sebagai perangkat dm-user, yang terhubung ke instance Daemon snapuserd.

{i>Kernel<i} tidak menggunakan format COW baru. Jadi, komponen snapuserd menerjemahkan permintaan antara format COW Android dan format:

Komponen snapuser yang menerjemahkan permintaan antara format COW Android dan kernel
bawaan
format

Gambar 3. Diagram alir snapuserd sebagai penerjemah antara Android dan Kernel Format COW

Penerjemahan dan dekompresi ini tidak pernah terjadi pada {i>disk<i}. snapuserd mencegat pembacaan dan penulisan COW yang terjadi di {i>kernel<i}, dan menerapkannya menggunakan format COW Android.

Kompresi XOR

Untuk perangkat yang diluncurkan dengan Android 13 dan yang lebih baru, Fitur kompresi XOR, yang diaktifkan secara default, memungkinkan userspace snapshot untuk menyimpan byte terkompresi XOR antara blok lama dan blok baru. Kapan hanya beberapa byte dalam sebuah blok yang diubah dalam update A/B Virtual, skema penyimpanan kompresi file menggunakan lebih sedikit ruang daripada skema penyimpanan default karena snapshot tidak menyimpan seluruh byte 4K. Pengurangan ukuran snapshot ini memungkinkan karena data XOR berisi banyak angka nol dan lebih mudah dikompresi daripada data memblokir data. Pada perangkat Pixel, kompresi XOR mengurangi ukuran snapshot sebesar 25% menjadi 40%.

Untuk perangkat yang diupgrade ke Android 13 dan yang lebih tinggi, XOR kompresi harus diaktifkan. Untuk mengetahui detailnya, lihat XOR kompresi.

Proses kompresi A/B virtual

Bagian ini memberikan detail tentang proses kompresi A/B Virtual yang digunakan dalam Android 13 dan Android 12.

Membaca metadata (Android 12)

Metadata dibuat oleh daemon snapuserd. {i>Metadata<i} pada dasarnya adalah pemetaan dua ID, masing-masing 8 byte, yang mewakili sektor yang akan digabungkan. Di dm-snapshot, ini disebut disk_exception.

struct disk_exception {
    uint64_t old_chunk;
    uint64_t new_chunk;
};

Pengecualian {i>disk<i} digunakan ketika bagian data lama diganti dengan data baru.

Daemon snapuserd membaca file COW internal melalui library COW dan menyusun {i>metadata<i} untuk setiap operasi COW yang ada dalam file COW tersebut.

Pembacaan metadata dimulai dari dm-snapshot dalam kernel saat perangkat dm- snapshot dibuat.

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

Diagram urutan, jalur IO untuk metadata
konstruksi

Gambar 4. Alur urutan untuk jalur IO dalam konstruksi metadata

Menggabungkan (Android 12)

Setelah proses booting selesai, mesin update menandai slot sebagai booting berhasil dan memulai penggabungan dengan mengalihkan target dm-snapshot ke Target dm-snapshot-merge.

dm-snapshot berjalan melalui metadata dan memulai IO gabungan untuk setiap disk pengecualian. Ringkasan tingkat tinggi dari jalur IO penggabungan ditampilkan di bawah.

Jalur IO gabungan

Gambar 5. Ringkasan jalur Merge IO

Jika perangkat di-reboot selama proses penggabungan, penggabungan akan dilanjutkan pada {i>reboot<i} berikutnya, dan penggabungan selesai.

Pelapisan mapper perangkat

Untuk perangkat yang diluncurkan dengan Android 13 dan yang lebih baru, Proses penggabungan snapshot dan snapshot dalam kompresi A/B Virtual dilakukan oleh komponen userspace snapuserd. Untuk perangkat yang mengupgrade ke Android 13 dan lebih tinggi, fitur ini harus diaktifkan. Sebagai detailnya, lihat Userspace penggabungan.

Berikut penjelasan tentang proses kompresi A/B Virtual:

  1. Framework ini memasang partisi /system dari perangkat dm-verity, yang ditumpuk di atas perangkat dm-user. Ini berarti bahwa setiap I/O dari sistem file root akan dirutekan ke dm-user.
  2. dm-user merutekan I/O ke daemon snapuserd userspace, yang menangani terhadap permintaan I/O.
  3. Setelah operasi penggabungan selesai, framework akan menciutkan dm-verity di di bagian atas dm-linear (system_base) dan menghapus dm-user.

Kompresi A/B virtual
proses

Gambar 6. Proses kompresi A/B virtual

Proses penggabungan snapshot dapat terganggu. Jika perangkat dimulai ulang selama proses penggabungan, proses penggabungan dilanjutkan setelah {i>reboot<i}.

Transisi init

Saat melakukan booting dengan snapshot terkompresi, init tahap pertama harus dimulai snapuserd untuk memasang partisi. Hal ini menimbulkan masalah: Saat sepolicy dimuat dan diterapkan, snapuserd ditempatkan dalam konteks yang salah, dan permintaan bacanya gagal, dengan penolakan selinux.

Untuk mengatasi hal ini, transisi snapuserd dalam langkah kunci dengan init, sebagai berikut:

  1. init tahap pertama meluncurkan snapuserd dari ramdisk, dan menyimpan deskriptif file dalam variabel lingkungan.
  2. init tahap pertama mengalihkan sistem file root ke partisi sistem, lalu menjalankan salinan sistem init.
  3. Salinan sistem init membaca sepolicy gabungan ke dalam string.
  4. Init memanggil mlock() di semua halaman yang didukung ext4. Kemudian menonaktifkan semua tabel pemetaan perangkat untuk perangkat snapshot, dan menghentikan snapuserd. Setelahnya dilarang membaca dari partisi, karena hal itu akan menyebabkan deadlock.
  5. Menggunakan deskriptor terbuka ke salinan ramdisk snapuserd, init meluncurkan ulang daemon dengan konteks selinux yang benar. Tabel peta perangkat untuk perangkat snapshot diaktifkan kembali.
  6. Init memanggil munlockall() - aman untuk melakukan IO lagi.

Penggunaan ruang

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

Dampak Ukuran non-A/B A/B A/B Virtual A/B virtual (dikompresi)
Gambar Pabrik Asli 4,5 GB super (3,8 G gambar + 700 JT reservasi)1 9GB super (3,8G + 700 juta cadangan, untuk dua slot) 4,5 GB super (3,8 G gambar + 700 juta cadangan) 4,5 GB super (3,8 G gambar + 700 juta cadangan)
Partisi statis lainnya /cache Tidak ada Tidak ada Tidak ada
Penyimpanan tambahan Selama OTA (ruang yang dikembalikan setelah menerapkan OTA) 1,4 GB aktif /data 0 3,8 GB2 pada /data 2,1 GB2 pada /data
Total penyimpanan yang diperlukan untuk menerapkan OTA 5,9 GB3 (super dan data) 9GB (super) 8,3 GB3 (super dan data) 6,6 GB3 (super dan data)

1Menunjukkan asumsi tata letak berdasarkan pemetaan Pixel.

2Mengasumsikan bahwa image sistem baru memiliki ukuran yang sama dengan aslinya.

3Persyaratan ruang bersifat sementara hingga perangkat dimulai ulang.

Untuk mengimplementasikan A/B Virtual, atau menggunakan kemampuan snapshot terkompresi, lihat Mengimplementasikan A/B Virtual