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 perangkatdm-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
.
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.
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:
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.
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.
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:
- Framework ini memasang partisi
/system
dari perangkatdm-verity
, yang ditumpuk di atas perangkatdm-user
. Ini berarti bahwa setiap I/O dari sistem file root akan dirutekan kedm-user
. dm-user
merutekan I/O ke daemonsnapuserd
userspace, yang menangani terhadap permintaan I/O.- Setelah operasi penggabungan selesai, framework akan menciutkan
dm-verity
di di bagian atasdm-linear
(system_base
) dan menghapusdm-user
.
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:
init
tahap pertama meluncurkansnapuserd
dari ramdisk, dan menyimpan deskriptif file dalam variabel lingkungan.init
tahap pertama mengalihkan sistem file root ke partisi sistem, lalu menjalankan salinan sisteminit
.- Salinan sistem
init
membaca sepolicy gabungan ke dalam string. Init
memanggilmlock()
di semua halaman yang didukung ext4. Kemudian menonaktifkan semua tabel pemetaan perangkat untuk perangkat snapshot, dan menghentikansnapuserd
. Setelahnya dilarang membaca dari partisi, karena hal itu akan menyebabkan deadlock.- Menggunakan deskriptor terbuka ke salinan ramdisk
snapuserd
,init
meluncurkan ulang daemon dengan konteks selinux yang benar. Tabel peta perangkat untuk perangkat snapshot diaktifkan kembali. - 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