Virtual A/B adalah mekanisme update utama Android. Virtual A/B dibuat berdasarkan update A/B lama (lihat Update Sistem A/B) dan non-A/B yang tidak digunakan lagi di Android 15 untuk mengurangi overhead ruang penyimpanan update.
Virtual A/B sebenarnya tidak memiliki slot tambahan untuk partisi dinamis, lihat partisi dinamis. Sebagai gantinya, delta ditulis ke snapshot, lalu digabungkan ke partisi dasar setelah mengonfirmasi booting yang berhasil. Virtual A/B menggunakan format snapshot khusus Android. Lihat format COW untuk snapshot terkompresi yang memungkinkan snapshot dikompresi dan meminimalkan penggunaan ruang disk. Pada OTA penuh, ukuran snapshot dikurangi sekitar 45% dengan kompresi, dan ukuran snapshot OTA inkremental dikurangi sekitar 55%.
Android 12 menawarkan opsi kompresi Virtual A/B untuk mengompresi partisi yang di-snapshot. Virtual A/B menawarkan hal berikut
- Update Virtual A/B tidak terganggu (update terjadi sepenuhnya di latar belakang saat perangkat beroperasi) seperti update A/B. Update Virtual A/B meminimalkan waktu perangkat offline dan tidak dapat digunakan.
- Update Virtual A/B dapat di-roll back. Jika OS baru gagal di-boot, perangkat akan otomatis di-roll back ke versi sebelumnya.
- Update Virtual A/B menggunakan ruang tambahan minimum dengan hanya menduplikasi partisi yang digunakan oleh bootloader. Partisi lain yang dapat diupdate di snapshot.
Latar Belakang dan terminologi
Bagian ini menentukan terminologi dan menjelaskan teknologi yang mendukung Virtual A/B. Selama penginstalan OTA, data sistem operasi baru ditulis ke slot baru untuk partisi fisik, atau perangkat COW khusus Android. Setelah perangkat di-reboot, data partisi dinamis digabungkan kembali ke perangkat dasarnya melalui penggunaan daemon dm-user dan snapuserd. Proses ini terjadi sepenuhnya di ruang pengguna.
Device-mapper
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 super fisik (misalnya,
/dev/block/by-name/super). - Di bagian tengah adalah perangkat
dm-linear, yang menentukan blok mana di partisi super yang membentuk partisi dinamis tertentu. Ini muncul sebagai/dev/block/mapper/system_[a|b]di perangkat A/B, atau/dev/block/mapper/systemdi perangkat non-A/B. - Di bagian atas terdapat perangkat
dm-verity, yang dibuat untuk partisi terverifikasi. Perangkat ini memverifikasi bahwa blok pada perangkatdm-linearditandatangani dengan benar. Perangkat ini muncul sebagai/dev/block/mapper/system-veritydan merupakan sumber direktori pemasangan/system
Gambar 1 menunjukkan tampilan tumpukan di bawah direktori pemasangan /system.
Gambar 1. Tumpukan di bawah direktori pemasangan /system
Snapshot terkompresi
Di Android 12 dan yang lebih baru, karena persyaratan ruang penyimpanan pada partisi /data dapat tinggi, Anda dapat mengaktifkan snapshot terkompresi dalam build untuk mengatasi persyaratan ruang penyimpanan yang lebih tinggi pada partisi /data.
Snapshot terkompresi Virtual A/B dibuat berdasarkan komponen berikut yang tersedia di Android 12 dan yang lebih baru:
dm-user, modul kernel yang mirip dengan FUSE yang memungkinkan ruang pengguna mengimplementasikan perangkat blok.snapuserd, daemon ruang pengguna untuk mengimplementasikan format snapshot baru.
Komponen ini memungkinkan kompresi. Perubahan lain yang diperlukan untuk mengimplementasikan kemampuan snapshot terkompresi diberikan di bagian berikutnya: Format COW untuk snapshot terkompresi, dm-user, dan snapuserd.
Format COW untuk snapshot terkompresi
Di Android 12 dan yang lebih baru, snapshot terkompresi menggunakan format COW khusus Android. Format COW berisi metadata tentang OTA dan memiliki buffer terpisah yang berisi operasi COW dan data sistem operasi baru. Dibandingkan dengan format snapshot kernel yang hanya mengizinkan operasi replace (Ganti blok X dalam image dasar dengan konten blok Y dalam snapshot), format COW snapshot terkompresi Android 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. Setiap blok ini dikompresi gz.
- Zero: Blok X di perangkat dasar harus diganti dengan semua nol.
- XOR: Perangkat COW menyimpan byte terkompresi XOR antara blok X dan blok Y. (Tersedia di Android 13 dan yang lebih baru.)
Update OTA penuh hanya terdiri dari operasi replace dan zero. Update OTA inkremental juga dapat memiliki operasi copy.
Tata letak snapshot lengkap di disk terlihat seperti ini:
Gambar 2. Format COW Android di Disk
dm-user
Modul kernel dm-user memungkinkan userspace mengimplementasikan perangkat blok device-mapper. Entri tabel dm-user membuat perangkat lain-lain di bawah
/dev/dm-user/<control-name>. Proses userspace dapat melakukan polling perangkat untuk menerima permintaan baca dan tulis dari kernel. Setiap permintaan memiliki buffer terkait untuk ruang pengguna yang akan diisi (untuk baca) atau disebarkan (untuk tulis).
Modul kernel dm-user menyediakan antarmuka baru yang terlihat oleh pengguna ke kernel yang bukan bagian dari basis kode kernel.org upstream. Hingga saat ini, Google berhak mengubah antarmuka dm-user di Android.
snapuserd
Komponen ruang pengguna snapuserd ke dm-user mengimplementasikan kompresi Virtual A/B. Snapuserd adalah daemon ruang pengguna yang bertanggung jawab untuk menulis dan membaca perangkat COW Android. Semua I/O ke snapshot harus melalui layanan ini.
Selama penginstalan OTA, data sistem operasi baru ditulis ke snapshot oleh snapuserd (dengan kompresi). Penguraian metadata dan pembongkaran data blok baru juga ditangani di sini.
Kompresi XOR
Untuk perangkat yang diluncurkan dengan Android 13 dan yang lebih baru, fitur kompresi XOR, yang diaktifkan secara default, memungkinkan snapshot ruang pengguna menyimpan byte terkompresi XOR antara blok lama dan blok baru. Jika hanya beberapa byte dalam blok yang diubah dalam update Virtual A/B, skema penyimpanan kompresi XOR menggunakan lebih sedikit ruang penyimpanan daripada skema penyimpanan default karena snapshot tidak menyimpan byte 4K penuh. Pengurangan ukuran snapshot ini dimungkinkan karena data XOR berisi banyak nol dan lebih mudah dikompresi daripada data blok mentah. Di perangkat Pixel, kompresi XOR mengurangi ukuran snapshot sebesar 25% hingga 40%.
Untuk perangkat yang diupgrade ke Android 13 dan yang lebih baru, kompresi XOR harus diaktifkan. Untuk mengetahui detailnya, lihat Kompresi XOR.
Penggabungan snapshot
Untuk perangkat yang diluncurkan dengan Android 13 dan yang lebih baru, proses penggabungan snapshot dan snapshot dalam kompresi Virtual A/B dilakukan oleh komponen ruang pengguna snapuserd. Untuk perangkat yang diupgrade ke Android 13 dan yang lebih baru, fitur ini harus diaktifkan. Untuk mengetahui
detailnya, lihat Penggabungan ruang pengguna.
Berikut ini menjelaskan proses kompresi Virtual A/B:
- Framework memasang partisi
/systemdari perangkatdm-verity, yang ditumpuk di atas perangkatdm-user. Artinya, setiap I/O dari sistem file root dirutekan kedm-user. dm-usermerutekan I/O ke daemonsnapuserdruang pengguna, yang menangani permintaan I/O.- Setelah operasi penggabungan selesai, framework akan menciutkan
dm-veritydi atasdm-linear(system_base) dan menghapusdm-user.
Gambar 3. Proses kompresi Virtual A/B
Proses penggabungan snapshot dapat terganggu. Jika perangkat di-reboot selama proses penggabungan, proses penggabungan akan dilanjutkan setelah reboot.
Transisi init
Saat melakukan booting dengan snapshot terkompresi, init tahap pertama harus memulai 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 masalah ini, snapuserd bertransisi secara sinkron dengan init, sebagai berikut:
inittahap pertama meluncurkansnapuserddari ramdisk, dan menyimpan deskriptor file terbuka ke dalamnya dalam variabel lingkungan.inittahap pertama mengalihkan sistem file root ke partisi sistem, lalu menjalankan salinan sisteminit.- Salinan sistem
initmembaca sepolicy gabungan ke dalam string. Initmemanggilmlock()di semua halaman yang didukung ext4. Kemudian, init akan menonaktifkan semua tabel device-mapper untuk perangkat snapshot, dan menghentikansnapuserd. Setelah itu, membaca dari partisi dilarang, karena tindakan tersebut menyebabkan kebuntuan.- Menggunakan deskriptor terbuka ke salinan ramdisk
snapuserd,initmeluncurkan ulang daemon dengan konteks selinux yang benar. Tabel device-mapper untuk perangkat snapshot diaktifkan kembali. - Init memanggil
munlockall()- IO dapat dilakukan lagi dengan aman.
Penggunaan ruang penyimpanan
Tabel berikut memberikan perbandingan penggunaan ruang penyimpanan untuk berbagai mekanisme OTA menggunakan ukuran OS dan OTA Pixel.
| Dampak Ukuran | non-A/B | A/B | Virtual A/B | Virtual A/B (terkompresi) |
|---|---|---|---|---|
| Image Pabrik Asli | Super 4,5 GB (image 3,8 GB + 700 MB yang dicadangkan)1 | Super 9 GB (3,8 GB + 700 MB yang dicadangkan, untuk dua slot) | Super 4,5 GB (image 3,8 GB + 700 MB yang dicadangkan) | Super 4,5 GB (image 3,8 GB + 700 MB yang dicadangkan) |
| Partisi statis lainnya | /cache | Tidak ada | Tidak ada | Tidak ada |
| Penyimpanan tambahan Selama OTA (ruang penyimpanan yang dikembalikan setelah menerapkan OTA) | 1,4 GB di /data | 0 | 3,8 GB2 di /data | 2,1 GB2 di /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 tata letak yang diasumsikan berdasarkan pemetaan Pixel.
2Mengasumsikan image sistem baru memiliki ukuran yang sama dengan image asli.
3Persyaratan ruang penyimpanan bersifat sementara hingga reboot.
Virtual A/B Android 11
Virtual A/B Android 11 ditulis ke partisi dinamis menggunakan format COW Kernel. Hal ini akhirnya tidak digunakan lagi karena format COW Kernel tidak mendukung kompresi.
Virtual A/B Android 12
Di Android 12, kompresi didukung dalam bentuk format COW khusus Android. Versi Virtual A/B ini memerlukan terjemahan COW khusus Android ke format COW Kernel. Pada akhirnya, hal ini diganti di Android 13 yang menghapus ketergantungan pada format COW Kernel dan juga dm-snapshot.
Untuk mengimplementasikan Virtual A/B, atau menggunakan kemampuan snapshot terkompresi, lihat Mengimplementasikan Virtual A/B