Ringkasan A/B virtual

A/B Virtual adalah mekanisme update utama Android. A/B Virtual dibangun di atas update A/B lama (lihat Update Sistem A/B) dan non-A/B yang tidak digunakan lagi di 15 untuk mengurangi overhead ruang update.

A/B Virtual sebenarnya tidak memiliki slot tambahan untuk partisi dinamis, lihat partisi dinamis. Sebagai gantinya, delta akan ditulis ke snapshot, lalu digabungkan ke partisi dasar setelah mengonfirmasi keberhasilan booting. A/B Virtual 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. A/B virtual menawarkan hal berikut

  • Update A/B virtual lancar (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 A/B virtual dapat di-roll back. Jika OS baru gagal di-boot, perangkat akan otomatis di-roll back ke versi sebelumnya.
  • Update A/B virtual menggunakan ruang tambahan minimum dengan menduplikasi hanya partisi yang digunakan oleh bootloader. Partisi lain yang dapat diupdate akan diambil snapshotnya.

Latar Belakang dan terminologi

Bagian ini mendefinisikan terminologi dan menjelaskan teknologi yang mendukung A/B virtual. Selama penginstalan OTA, data sistem operasi baru akan ditulis ke slot barunya untuk partisi fisik, atau perangkat COW khusus Android. Setelah perangkat dimulai ulang, data partisi dinamis digabungkan kembali ke perangkat dasarnya melalui penggunaan daemon dm-user dan snapuserd. Proses ini sepenuhnya terjadi 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 stack adalah partisi super fisik (misalnya, /dev/block/by-name/super).
  • Di tengah ada perangkat dm-linear, yang menentukan blok mana dalam superpartisi yang membentuk partisi dinamis tertentu. Ini muncul sebagai /dev/block/mapper/system_[a|b] di perangkat A/B, atau /dev/block/mapper/system di perangkat non-A/B.
  • Di bagian atas terdapat perangkat dm-verity, yang dibuat untuk partisi terverifikasi. Perangkat ini memverifikasi bahwa blok pada perangkat dm-linear ditandatangani dengan benar. Direktori ini muncul sebagai /dev/block/mapper/system-verity dan merupakan sumber dari titik pemasangan /system.

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

Penumpukan partisi di bawah
sistem

Gambar 1. Stack di bawah direktori pemasangan /system

Snapshot terkompresi

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

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

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

Komponen ini memungkinkan kompresi. Perubahan lain yang diperlukan untuk menerapkan kemampuan snapshot terkompresi diberikan di bagian berikutnya: Format COW untuk snapshot terkompresi, dm-user, dan snapuserd.

Format COW untuk snapshot yang dikompresi

Di Android 12 dan yang lebih tinggi, snapshot terkompresi menggunakan format COW khusus Android. Format COW berisi metadata tentang OTA dan memiliki buffer berbeda 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.
  • Nol: Blok X di perangkat dasar harus diganti dengan semua nol.
  • XOR: Perangkat COW menyimpan byte yang dikompresi XOR antara blok X dan blok Y. (Tersedia di Android 13 dan yang lebih tinggi.)

Update OTA penuh hanya terdiri dari operasi replace dan zero. Update OTA inkremental juga dapat memiliki operasi copy.

Tata letak snapshot lengkap di disk akan terlihat seperti ini:

format sapi

Gambar 2. Format COW Android di Disk

dm-user

Modul kernel dm-user memungkinkan userspace menerapkan perangkat blok device-mapper. Entri tabel dm-user membuat perangkat lain-lain di bagian /dev/dm-user/<control-name>. Proses userspace dapat melakukan polling pada perangkat untuk menerima permintaan baca dan tulis dari kernel. Setiap permintaan memiliki buffer terkait untuk ruang pengguna yang akan diisi (untuk pembacaan) atau dipropagasi (untuk penulisan).

Modul kernel dm-user menyediakan antarmuka baru yang terlihat oleh pengguna ke kernel yang bukan bagian dari basis kode kernel.org upstream. Hingga saat itu, Google berhak mengubah antarmuka dm-user di Android.

snapuserd

Komponen ruang pengguna snapuserd hingga dm-user mengimplementasikan kompresi A/B Virtual. Snapuserd adalah daemon ruang pengguna yang bertugas 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 tinggi, fitur kompresi XOR, yang diaktifkan secara default, memungkinkan snapshot ruang pengguna menyimpan byte yang dikompresi XOR antara blok lama dan blok baru. Jika hanya beberapa byte dalam blok yang diubah dalam update A/B Virtual, skema penyimpanan kompresi XOR menggunakan lebih sedikit ruang daripada skema penyimpanan default karena snapshot tidak menyimpan 4K byte penuh. Pengurangan ukuran snapshot ini dapat dilakukan karena data XOR berisi banyak angka nol dan lebih mudah dikompresi daripada data blok mentah. Di perangkat Pixel, kompresi XOR mengurangi ukuran snapshot sebesar 25% hingga 40%.

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

Penggabungan snapshot

Untuk perangkat yang diluncurkan dengan Android 13 dan yang lebih tinggi, proses penggabungan snapshot dan snapshot dalam kompresi A/B Virtual dilakukan oleh komponen ruang pengguna snapuserd. Untuk perangkat yang mengupgrade ke Android 13 dan yang lebih tinggi, fitur ini harus diaktifkan. Untuk mengetahui detailnya, lihat Penggabungan ruang pengguna.

Berikut adalah deskripsi proses kompresi A/B Virtual:

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

Proses kompresi A/B virtual

Gambar 3. Proses kompresi A/B virtual

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 pembacaannya gagal, dengan penolakan selinux.

Untuk mengatasi hal ini, transisi snapuserd selaras dengan init, sebagai berikut:

  1. init tahap pertama meluncurkan snapuserd dari ramdisk, dan menyimpan deskriptor file yang terbuka ke dalamnya dalam variabel lingkungan.
  2. init tahap pertama mengalihkan sistem file root ke partisi sistem, lalu menjalankan salinan init sistem.
  3. Salinan sistem init membaca sepolicy gabungan ke dalam string.
  4. Init memanggil mlock() di semua halaman yang didukung ext4. Kemudian, menonaktifkan semua tabel device-mapper untuk perangkat snapshot, dan menghentikan snapuserd. Setelah ini, membaca dari partisi dilarang karena dapat menyebabkan kebuntuan.
  5. Dengan menggunakan deskriptor terbuka ke salinan ramdisk snapuserd, init meluncurkan kembali daemon dengan konteks selinux yang benar. Tabel device-mapper untuk perangkat snapshot diaktifkan kembali.
  6. Init memanggil munlockall() - aman untuk melakukan IO lagi.

Penggunaan ruang

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

Dampak Ukuran non-A/B A/B A/B Virtual A/B virtual (dikompresi)
Gambar Pabrik Asli Super 4,5 GB (gambar 3,8 GB + 700 MB yang dipesan)1 Super 9 GB (3,8 G + 700 M yang dicadangkan, untuk dua slot) Super 4,5 GB (gambar 3,8 GB + 700 MB yang dicadangkan) Super 4,5 GB (gambar 3,8 GB + 700 MB yang dicadangkan)
Partisi statis lainnya /cache Tidak ada Tidak ada Tidak ada
Penyimpanan tambahan Selama OTA (ruang 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 berukuran sama dengan image asli.

3Persyaratan ruang bersifat sementara hingga perangkat dimulai ulang.

A/B Virtual Android 11

Android 11 Virtual A/B menulis ke partisi dinamis menggunakan format COW Kernel. Format ini akhirnya dihentikan 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 digantikan di Android 13 yang menghapus ketergantungan pada format COW Kernel dan juga dm-snapshot.

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