Author: admin

  • Beyond Read-Only: Hacking Android System Apps with OverlayFS for Permanent Modifications

    The Immutable Android System: A Challenge for Advanced Customization

    Android’s core operating system resides on a partition typically mounted as read-only. This design choice by manufacturers enhances security, prevents accidental system corruption, and streamlines Over-The-Air (OTA) updates. For most users, this ‘immutability’ is beneficial. However, for advanced users, developers, and power users seeking deeper control, this read-only constraint presents a significant hurdle. Traditional modifications often involve directly flashing patched system images or relying on volatile runtime patches that don’t persist across reboots or updates.

    Imagine wanting to permanently alter a system application’s configuration file, modify a framework resource, or even replace a core system binary without rebuilding an entire ROM. While Magisk modules offer a powerful way to achieve systemless modifications, there are scenarios where a more direct, yet still layered, approach is desired. This is where OverlayFS steps in, offering an elegant solution to achieve persistent, yet reversible, modifications on an otherwise immutable system partition.

    Understanding OverlayFS: A Layered Approach to File Systems

    OverlayFS is a union mount filesystem service that allows you to combine multiple file systems into a single, unified view. It works by layering one filesystem (the ‘upper’ layer) on top of another (the ‘lower’ layer). When a file is accessed in the merged view:

    • If the file exists only in the `lowerdir`, it’s read directly from there.
    • If the file exists in both `lowerdir` and `upperdir`, the version from `upperdir` is used (effectively ‘overriding’ the lower version).
    • If a file is modified or created in the `merged` view, it’s actually written to the `upperdir`.
    • Deletions are handled by creating ‘whiteout’ files in the `upperdir`, making the corresponding `lowerdir` file appear deleted in the `merged` view without actually touching the original.

    For our purposes, the read-only Android /system partition will serve as the lowerdir. A writable directory, typically on the /data partition, will be our upperdir. All modifications will be written to this upperdir, leaving the original /system untouched. A workdir is also required for internal OverlayFS operations.

    Prerequisites: Gearing Up for System Overlays

    Before diving in, ensure you have the following:

    • Rooted Android Device: Essential for accessing and modifying system-level files and mounting custom filesystems.
    • Custom Recovery (TWRP Recommended): Provides a secure environment to unmount system partitions and execute shell commands without the Android OS running.
    • Basic Linux Command-Line Knowledge: Familiarity with commands like mount, mkdir, cp, mv, rm, ls, cat.
    • Kernel Support for OverlayFS: Most modern Android kernels (especially those running on Android 9.0+) include OverlayFS support. You can check this by looking for CONFIG_OVERLAYFS in your kernel config or by trying to run a simple mount -t overlay command.
    • Backup: Always perform a full Nandroid backup via TWRP before making any system-level modifications. This is your lifeline if something goes wrong.

    Step-by-Step Guide: Implementing OverlayFS for /system

    Step 1: Backup Your Device

    Boot into TWRP. Go to Backup and create a full system, data, and boot backup. Store it safely.

    Step 2: Boot into TWRP Recovery and Access Shell

    Reboot your device into TWRP. From the main menu, go to ‘Advanced’ -> ‘Terminal’ or connect your device to a PC and use adb shell.

    Step 3: Prepare Overlay Directories

    We need directories on the writable /data partition to store our modifications (upperdir) and for OverlayFS’s internal use (workdir).

    adb shell # If using PC, otherwise you're already in shellmkdir -p /data/overlay/system_uppermkdir -p /data/overlay/system_work

    Step 4: Unmount /system and Create Merge Point

    The /system partition is likely mounted. We need to unmount it to use it as the lowerdir. Then, we create a temporary mount point where our merged OverlayFS view will be accessible.

    umount /systemmkdir -p /mnt/system_overlay

    Note: In some TWRP versions, /system might be mounted as /system_root on A/B devices. Adjust paths accordingly. You can check with mount | grep system.

    Step 5: Mount OverlayFS

    Now, we create the OverlayFS union mount. Replace /dev/block/by-name/system with the actual block device for your system partition if necessary (use ls -l /dev/block/by-name/system to check the symlink target).

    mount -t overlay overlay -o lowerdir=/system,upperdir=/data/overlay/system_upper,workdir=/data/overlay/system_work /mnt/system_overlay

    Let’s break down the command:

    • mount -t overlay overlay: Specifies the filesystem type as ‘overlay’. The second ‘overlay’ is a dummy device name.
    • -o lowerdir=/system: Defines the original read-only /system partition as the base layer.
    • upperdir=/data/overlay/system_upper: Specifies our writable directory for modifications.
    • workdir=/data/overlay/system_work: Designates a temporary directory required by OverlayFS.
    • /mnt/system_overlay: This is the directory where the merged filesystem will be accessible. Any changes made here will be reflected in /data/overlay/system_upper.

    Verify the mount:

    mount | grep system_overlay

    You should see an entry for the overlay mount.

    Step 6: Perform Your System Modifications

    Now, navigate into /mnt/system_overlay. This is your writable view of the system. You can create, modify, or delete files, and these changes will be stored in /data/overlay/system_upper.

    Example: Modifying build.prop

    Let’s say you want to add a line to /system/build.prop for a specific customization (e.g., enabling camera2 API, though this often requires more than just build.prop tweaks).

    # Make a backup first!cp /mnt/system_overlay/system/build.prop /mnt/system_overlay/system/build.prop.bak# Edit build.prop - using a temporary file is safer and easier in shellcp /mnt/system_overlay/system/build.prop /tmp/my_build.propecho

  • Reverse Engineering Android’s A/B Updates: Where and How to Inject Persistent Changes via OverlayFS

    Introduction to Android A/B Updates and Immutability

    Android’s A/B (seamless) update system has revolutionized how operating system updates are delivered, significantly enhancing reliability and user experience. By maintaining two identical system partitions (A and B), updates can be applied to the inactive slot in the background. If an update fails, the device can simply revert to the previous, working slot. This system, however, introduces a formidable challenge for advanced users and developers: achieving persistent, system-level modifications. The core issue lies in the read-only nature of the active system partition and the way updates overwrite the inactive one. Traditional methods of modifying /system often fail to survive reboots or updates.

    This article dives deep into leveraging OverlayFS to inject persistent changes into an A/B partitioned Android system. OverlayFS provides a flexible mechanism to create a writable layer over a read-only filesystem, allowing modifications to appear permanent without altering the underlying immutable partitions. This technique is crucial for custom ROM developers, security researchers, and enthusiasts looking to deeply customize their Android devices beyond typical root access.

    The Mechanics of Android A/B Updates

    Android A/B updates operate on a simple yet effective principle. A device typically has two sets of partitions: system_a, vendor_a, boot_a, and system_b, vendor_b, boot_b. At any given time, one set is

  • Mastering Android’s Immutable Core: Persistent Customizations with OverlayFS

    Introduction: The Immutable Android Challenge

    Modern Android operating systems, particularly those leveraging A/B seamless updates and Project Treble, increasingly rely on an immutable system partition. This design choice enhances security, improves update reliability, and simplifies device management. However, it presents a significant hurdle for advanced users and developers who wish to apply persistent, low-level customizations to their device’s core system files. Modifying files directly on a read-only /system or /system_root partition is either impossible or requires disruptive, often temporary, workarounds.

    Enter OverlayFS – a powerful Linux kernel feature that allows you to layer one filesystem over another. It presents a unified view where changes appear to be written to the lower, read-only filesystem, but are actually stored in an upper, writable directory. This article will guide you through the process of leveraging OverlayFS to achieve persistent system customizations on Android, making your modifications survive reboots and even system updates (with careful planning).

    Understanding OverlayFS Fundamentals

    OverlayFS operates on a simple yet effective principle: it combines multiple filesystems into a single, unified view. At its core, it uses:

    • Lower Directory (lowerdir): This is your immutable, read-only system partition (e.g., /system_root). Files here are visible but cannot be modified directly.
    • Upper Directory (upperdir): This is a writable directory, typically on a persistent storage location like /data. All modifications, additions, and deletions appear here.
    • Work Directory (workdir): A temporary, empty directory also on a writable filesystem, required by OverlayFS for internal operations. It must be empty when the mount is performed.
    • Merged Directory (mergedir): The final, unified view where you interact with your customized system. Files from the upperdir take precedence over those in the lowerdir.

    When you read a file, OverlayFS first checks the upperdir. If found, it reads from there. If not, it falls back to the lowerdir. When you write, modify, or delete a file, the changes are directed to the upperdir. If a file exists in the lowerdir but not the upperdir, modifying it triggers a ‘copy_up’ operation, copying the original file to the upperdir before applying changes.

    Prerequisites and Initial Setup

    Before diving into OverlayFS, ensure you have the following:

    • Rooted Android Device: Magisk is highly recommended for its systemless approach.
    • Custom Recovery (Optional but Recommended): Such as TWRP, for emergency flashing or direct filesystem access.
    • ADB and Fastboot Setup: For interacting with your device from a computer.
    • Basic Linux Command Line Knowledge: Familiarity with mount, mkdir, cp, chmod, etc.

    Identifying Your Target Partition

    Modern Android devices often use a /system_root setup where /system is merely a symlink or bind mount within /system_root. You need to identify the actual partition containing the read-only system files. You can often find this using mount or by checking your device’s `fstab` entries:

    adb shellmount | grep ' / 'adb shellcat /proc/mounts | grep ' /system'

    Look for the root filesystem mount or the actual /system partition. For many devices, /system_root is the effective root of the immutable system. Let’s assume /system_root is our target for this guide.

    Preparing Directories on /data

    Since /data is always writable and persistent, we’ll create our OverlayFS directories there. Connect your device via ADB and open a shell:

    adb shellsu# Ensure you have root permissions# Create parent directory for OverlayFS structuresmkdir -p /data/overlayfs# Create upper, work, and merged directoriesmkdir -p /data/overlayfs/upperdir/systemmkdir -p /data/overlayfs/workdir/systemmkdir -p /data/overlayfs/merged/system

    The /system subdirectories are crucial because we’ll be overlaying on /system_root or /system directly. If your lowerdir is /system_root, you’d target /data/overlayfs/upperdir/system_root and /data/overlayfs/merged/system_root. For simplicity, we’ll target /system as the ‘visible’ system partition in this guide.

    Manual OverlayFS Implementation (Test Only)

    Before making it persistent, let’s test a manual mount. This should be done on a fresh boot with no existing modifications to the target system files.

    adb shellsu# Unmount the existing /system partition (if it's a bind mount or similar)umount /system# Mount OverlayFS. Replace /system with your actual target if different.mount -t overlay overlay -olowerdir=/system,upperdir=/data/overlayfs/upperdir/system,workdir=/data/overlayfs/workdir/system /data/overlayfs/merged/system# Then, bind mount the merged directory to /systemmount -o bind /data/overlayfs/merged/system /system

    Now, if you list the contents of /system, you’re actually seeing the merged view. You can test a customization:

    # Create a test file inside the 'customized' systemecho 'Hello OverlayFS!' > /system/overlay_test.txt# Verify it's therecat /system/overlay_test.txt# Check if it appeared in your upperdir (it should)cat /data/overlayfs/upperdir/system/overlay_test.txt

    This manual mount will disappear on reboot. To revert, simply reboot your device or manually unmount and remount the original system.

    Automating Persistence with Magisk

    The most robust way to make OverlayFS persistent on Android is through a Magisk module. Magisk’s post-fs-data.sh script executes very early in the boot process, allowing us to perform the necessary mounts before Android fully initializes.

    Magisk Module Structure

    A basic Magisk module for OverlayFS needs the following structure:

    overlayfs_module/├── module.prop├── customize.sh  (Optional, for initial setup if needed)└── post-fs-data.sh

    module.prop Example

    module.prop contains module metadata:

    id=overlayfs_customizername=OverlayFS Persistent System Customizerversion=v1.0versionCode=1author=Your NameDescription=Enables persistent system modifications via OverlayFS.

    post-fs-data.sh Example

    This is where the core logic resides. It will create directories (if they don’t exist) and perform the mount:

    #!/system/bin/sh# Wait for /data to be fully availablewhile [ "$(getprop sys.boot_completed)" != "1" ]; do  sleep 1;done# Define pathsLOWER_DIR="/system" # Or /system_root depending on your deviceOVERLAY_ROOT="/data/overlayfs"UPPER_DIR="$OVERLAY_ROOT/upperdir/system"WORK_DIR="$OVERLAY_ROOT/workdir/system"MERGED_DIR="$OVERLAY_ROOT/merged/system"# Create directories if they don't exist (Magisk module install might already do this)mkdir -p "$UPPER_DIR"mkdir -p "$WORK_DIR"mkdir -p "$MERGED_DIR"# Ensure workdir is empty for each mountrm -rf "${WORK_DIR}/*" "${WORK_DIR}/.*" # Clear hidden files too# Unmount existing /system if it's a bind mount or similar (critical for some devices)if mount | grep -q "$MERGED_DIR on /system"; then  umount /systemfi# Perform the OverlayFS mountmount -t overlay overlay -olowerdir="$LOWER_DIR",upperdir="$UPPER_DIR",workdir="$WORK_DIR" "$MERGED_DIR"# Check if OverlayFS mount was successfulif [ $? -ne 0 ]; then  log -p E "OverlayFS: Failed to mount overlay."  exit 1fi# Now bind mount the merged directory to the actual /system locationumount /system # Unmount the original system if mountedread-onlymount -o bind "$MERGED_DIR" "/system"if [ $? -ne 0 ]; then  log -p E "OverlayFS: Failed to bind mount merged directory to /system."  exit 1fi# Log successlog -p I "OverlayFS: Persistent system customizations active!"

    Building and Flashing the Module

    1. Save the above files into the overlayfs_module directory.
    2. Zip the entire overlayfs_module directory (ensure module.prop is at the root of the zip).
    3. Transfer the zip to your Android device.
    4. Open Magisk Manager, go to ‘Modules’, tap ‘Install from storage’, and select your zip file.
    5. Reboot your device.

    After reboot, any changes you make to /system will be stored in /data/overlayfs/upperdir/system and persist across reboots.

    Example Customization: Modifying build.prop

    Let’s say you want to change your device model name reported in settings or enable a hidden feature flag in build.prop. With OverlayFS active, you can directly edit it:

    adb shellsu# Now you're interacting with the merged filesystemvi /system/build.prop # Or use a text editor of your choice# Make your desired changes, e.g., add or modify a propertyecho 'ro.product.custom_feature=true' >> /system/build.prop# Verify the changecat /system/build.prop | grep 'custom_feature'

    These changes will now survive reboots. If you uninstall the Magisk module, the /data/overlayfs directories will remain, but the OverlayFS mount won’t occur, and your system will revert to its original immutable state (unless you delete the files in /data/overlayfs/upperdir/system manually).

    Troubleshooting and Best Practices

    • Bootloops: If your device bootloops after installing the module, it’s likely due to an incorrect mount command or a critical system file being corrupted. Boot into safe mode (if possible) or recovery, disable the Magisk module, and delete the /data/overlayfs directories.
    • Performance: While OverlayFS is efficient, heavy I/O operations on overlaid files might introduce a slight performance overhead.
    • Updates: System updates (especially A/B updates) typically replace the lowerdir. Your upperdir will remain, but conflicts can arise if the original file structure changes significantly. Always back up your upperdir before major updates.
    • Security: Be extremely cautious about what you modify. Incorrect changes can destabilize your system or create security vulnerabilities.
    • Cleaning Up: To remove customizations, delete the corresponding files from /data/overlayfs/upperdir/system. To completely revert to stock, uninstall the Magisk module and delete the entire /data/overlayfs directory.

    Conclusion

    OverlayFS provides an elegant and powerful solution for achieving persistent system-level customizations on immutable Android devices. By understanding its principles and carefully crafting a Magisk module, you can break free from the constraints of read-only partitions, tailoring your Android experience to your exact needs without compromising system integrity or update mechanisms. This expert guide equips you with the knowledge to harness this Linux kernel feature for advanced Android modding.

  • The OverlayFS Toolkit: Automating Persistent Android System Tweaks and App Installs

    Introduction: The Immutable Android System Challenge

    Modern Android systems, particularly those leveraging ‘system-as-root’ and Project Treble, have adopted a highly immutable architecture. The core `/system` partition is typically mounted read-only, ensuring system integrity, enhancing security, and facilitating seamless over-the-air (OTA) updates. While these advancements bring significant benefits to device stability and user security, they pose a formidable challenge for power users and developers who wish to apply persistent system-level modifications, install apps directly to system partitions, or deeply customize their device’s behavior. Any changes made to `/system` are transient; they are lost upon reboot or overwritten by the next OTA update.

    This is where OverlayFS steps in. OverlayFS is a union filesystem service that allows you to combine multiple directory trees into a single, unified view. Crucially, it enables a read-write layer to sit atop a read-only layer, making it an elegant solution for achieving persistent modifications on immutable file systems like Android’s `/system` partition.

    Understanding OverlayFS Fundamentals

    OverlayFS operates on a principle known as ‘copy-on-write’. When you attempt to modify a file that exists in the read-only layer, OverlayFS transparently copies that file to a writable layer before applying the changes. This ensures the original read-only base remains untouched while providing the illusion of a fully writable filesystem.

    Key Components: Lower, Upper, Work, and Merged Directories

    • Lower Directory (lowerdir): This is the original, typically read-only, filesystem you want to modify. In our Android context, this will be your `/system` partition. OverlayFS reads existing files from here.
    • Upper Directory (upperdir): This is a writable directory where all modifications (new files, modified files, deletions) are stored. On Android, this will reside on a writable partition like `/data`.
    • Work Directory (workdir): This is a temporary, empty directory within the same filesystem as the upperdir. OverlayFS uses it for internal operations and to prepare file moves and renames. It must be empty when the OverlayFS is mounted.
    • Merged Directory: This is the unified view presented to the user. It combines the contents of the lowerdir and upperdir. When you navigate or interact with files in the merged directory, OverlayFS decides whether to retrieve them from the lowerdir (if untouched) or the upperdir (if modified or new).

    When a file is modified, its new version is stored in the upperdir. If a file is deleted from the merged view, OverlayFS creates a special ‘whiteout’ file in the upperdir, signaling that the file from the lowerdir should be hidden. New files are simply created directly in the upperdir.

    Prerequisites for OverlayFS Implementation on Android

    Before diving into the setup, ensure you have the following prerequisites in place:

    • Rooted Android Device: Essential for accessing and modifying core system files and running privileged commands.
    • Custom Recovery (e.g., TWRP): Useful for initial backups, flashing necessary tools, and sometimes for gaining initial shell access outside the booted OS.
    • ADB Access: Android Debug Bridge is crucial for sending shell commands to your device from your computer.
    • busybox or toybox with OverlayFS support: Modern Android devices typically include a `toybox` implementation that supports `mount -t overlay`. If not, you may need to install `busybox` (or a `busybox` Magisk module) to ensure the `mount` command has the necessary capabilities.
    • Basic Linux Shell Knowledge: Familiarity with commands like `ls`, `mkdir`, `mount`, `cp`, `chmod`, `chown`.
    • Backup Your Device!: While OverlayFS is relatively safe as it doesn’t modify the `lowerdir`, errors in setup can lead to boot loops. Always back up critical data.

    Step-by-Step OverlayFS Setup for Persistent Tweaks

    This guide assumes you are performing these actions via an adb shell with root privileges (su).

    1. Identify Target Partitions and Prepare Directories

    First, identify your read-only `/system` partition. On many devices, it’s mounted directly at `/system`, but the underlying block device might vary.

    adb shellsu# Check current mounts and identify /systemmount | grep /system

    You’ll typically see something like `/dev/block/dm-0 on /system type ext4 (ro,seclabel,relatime,block_validity,delalloc,barrier,user_xattr)` indicating a read-only mount. Note the actual mount point (`/system`).

    Next, create the upperdir and workdir on a writable partition. The `/data` partition is the ideal choice for this, as it is always writable and typically has ample space.

    mkdir -p /data/overlay/system_upper/mkdir -p /data/overlay/system_work/

    2. Unmount and Remount the Original System (if necessary)

    For OverlayFS to correctly take over, the original `/system` mount point needs to be free or mounted read-only. If your `/system` is already read-only, you likely don’t need to unmount it. If it was temporarily remounted read-write, ensure it’s unmounted first.

    umount /system # Only if currently mounted read-write. If already RO, this might fail or isn't needed.

    3. Mount the OverlayFS Layer

    This is the core command that brings OverlayFS to life. We will mount the overlay *over* the existing `/system` mount point.

    mount -t overlay overlay -o lowerdir=/system,upperdir=/data/overlay/system_upper,workdir=/data/overlay/system_work /system
    • -t overlay: Specifies the filesystem type as OverlayFS.
    • overlay: The device argument for OverlayFS (it’s a pseudo-filesystem, so this is just a name).
    • lowerdir=/system: The base read-only layer.
    • upperdir=/data/overlay/system_upper: The writable layer where changes are stored.
    • workdir=/data/overlay/system_work: The temporary working directory.
    • /system: The mount point where the merged view will be accessible.

    4. Verify the OverlayFS Mount

    After executing the mount command, verify that OverlayFS is active and correctly mounted:

    mount | grep overlay

    You should see an entry similar to: `overlay on /system type overlay (rw,relatime,lowerdir=/system,upperdir=/data/overlay/system_upper,workdir=/data/overlay/system_work)`

    To further test, try creating a dummy file in `/system` and then check if it appears in your `upperdir`:

    touch /system/test_overlay_file.txtls /data/overlay/system_upper/test_overlay_file.txt

    If the file is visible in both `/system` and `/data/overlay/system_upper`, your OverlayFS is working correctly!

    Practical Applications: Persistent App Installs and System Modifications

    Installing a System App Persistently

    Let’s say you want to install an app directly into the `/system/priv-app` directory, making it a privileged system app that persists across reboots.

    # Create the app directory in the merged /systemadb shell# Make sure you are rootsu# Create directory for your appmkdir -p /system/priv-app/MyCustomApp# Push the APK file (from your computer)adb push MyCustomApp.apk /system/priv-app/MyCustomApp/MyCustomApp.apk# Set correct permissions and ownershipchown root:root /system/priv-app/MyCustomApp/MyCustomApp.apkchmod 644 /system/priv-app/MyCustomApp/MyCustomApp.apk

    After rebooting, the app will still be present and function as a system app because its files are stored in `/data/overlay/system_upper/priv-app/MyCustomApp/`.

    Modifying System Configuration Files

    You can also persistently modify existing system files, like `build.prop`.

    # Make a backup (will be in upperdir)cp /system/build.prop /system/build.prop.bak# Append a custom propertyecho

  • Migrate Any Android ROM with Btrfs send/receive: Zero-Downtime System Transfers & Upgrades

    Introduction: The Btrfs Advantage for Android ROM Migrations

    Migrating Android ROMs, whether for upgrades, switching distributions, or simply replicating a setup, traditionally involves significant downtime and data loss. Users often resort to complex backup solutions or face the tedious process of reinstalling apps and reconfiguring settings. This article unveils an advanced, expert-level technique using Btrfs filesystem’s powerful send/receive capabilities to perform near zero-downtime Android system transfers and upgrades.

    Btrfs, a modern Copy-on-Write (CoW) filesystem, offers features like snapshots, subvolumes, and data integrity that are revolutionary for system management. Its send/receive mechanism allows for efficient, incremental synchronization of filesystem snapshots, making it perfect for mirroring or updating Android installations with minimal interruption.

    Prerequisites for Btrfs-Powered Android Migration

    Before diving into the process, ensure you have the following:

    • Rooted Android Device(s): Both source and target devices must be rooted.
    • Custom Recovery with Btrfs Support: TWRP or similar, compiled with Btrfs filesystem support.
    • Btrfs Filesystem on Devices: Your / and /data partitions (or their equivalents) must be formatted as Btrfs. This is often the most significant hurdle and may require re-partitioning or flashing a custom kernel that supports Btrfs from the start.
    • Linux Host Machine: A PC running Linux with btrfs-progs installed. This will act as the intermediary for transfers.
    • ADB and Fastboot Tools: Installed and configured on your Linux host.
    • Sufficient Storage: The host machine needs enough space to temporarily store full snapshots of your Android partitions.

    Understanding Btrfs Key Concepts for Android

    To leverage Btrfs effectively, a grasp of its core features is essential:

    Subvolumes

    Btrfs subvolumes are like independent filesystems that share a common pool of disk space. Unlike traditional partitions, they are flexible and can be nested. For Android, you’ll typically have separate subvolumes for the root filesystem (/, e.g., @) and user data (/data, e.g., @data).

    Snapshots

    A snapshot is a read-only or read-write copy of a subvolume at a specific point in time. Because of CoW, snapshots are extremely efficient, initially consuming no extra disk space as they share data blocks with their parent. They become indispensable for creating consistent backups and for the send/receive process.

    Send/Receive

    This is the magic behind efficient data transfer. btrfs send generates a stream of data representing the changes between two snapshots (or a full snapshot). btrfs receive then applies this stream to a target Btrfs filesystem, recreating the subvolume and its contents. This allows for both full and incremental transfers.

    Step-by-Step Migration Guide

    This guide assumes you are migrating a source Android device (Device A) to a target Android device (Device B) via a Linux host.

    Step 1: Prepare the Source Device (Device A)

    Boot Device A into custom recovery. Mount its Btrfs partitions. Identify your root and data subvolumes (e.g., @ and @data). If you don’t have them, create them and move your data:

    adb shell
    mount -o compress=zstd /dev/block/by-name/system /mnt/system # Adjust block device path
    mount -o compress=zstd /dev/block/by-name/userdata /mnt/data # Adjust block device path
    # If you don't have subvolumes already, create them and move content
    btrfs subvolume create /mnt/system/@
    btrfs subvolume create /mnt/data/@data
    # Move existing files into subvolumes if necessary. This can be complex.
    # Assuming your ROM is already in a subvolume, e.g., @
    btrfs subvolume list /mnt/system
    btrfs subvolume list /mnt/data
    # Create snapshots of your active system and data subvolumes
    btrfs subvolume snapshot -r /mnt/system/@ /mnt/system/@_snap_initial
    btrfs subvolume snapshot -r /mnt/data/@data /mnt/data/@data_snap_initial
    exit

    Step 2: Initial Full Transfer (Source to Linux Host)

    Connect Device A to your Linux host. We will use adb exec-out to stream the Btrfs data directly.

    # Transfer system snapshot
    adb exec-out

  • Build Your Own Btrfs RAID Array on Android: Boost Performance & Data Redundancy for Advanced Users

    Unleashing Advanced Storage: Btrfs RAID on Android

    For the uninitiated, the idea of running a RAID array on an Android device might sound like science fiction. However, for advanced users seeking unparalleled control over their storage, enhanced performance, and robust data redundancy, integrating a Btrfs RAID setup is not only possible but also incredibly powerful. This guide will walk you through the intricate process of setting up a Btrfs RAID array using external USB storage on a rooted Android device, transforming your mobile workstation into a data management powerhouse.

    Btrfs, or B-tree file system, is a modern copy-on-write (CoW) filesystem for Linux that offers a wealth of advanced features, including snapshots, checksums, data and metadata integrity, self-healing capabilities, and integrated RAID functionality. While typically found in server environments or desktop Linux distributions, its adaptability makes it a compelling choice for pushing the boundaries of Android storage.

    Why Btrfs RAID on Android?

    The primary motivations for implementing Btrfs RAID on your Android device are:

    • Performance Boost: RAID 0 (striping) can significantly increase read and write speeds by spreading data across multiple disks.
    • Data Redundancy: RAID 1 (mirroring) provides fault tolerance, ensuring your data remains accessible even if one drive fails.
    • Advanced Features: Leverage Btrfs’s native snapshots for quick backups and rollbacks, copy-on-write functionality, and efficient space management.
    • Flexibility: Easily add or remove devices from your array, change RAID levels (with some limitations), and perform online filesystem checks.

    Before diving in, be aware that this is an advanced procedure that carries risks, including potential data loss or device instability if not executed carefully. A deep understanding of Linux command-line tools, Android rooting, and filesystem concepts is essential.

    Prerequisites for Your Android Btrfs RAID

    Setting up Btrfs RAID on Android requires more than just a rooted device. You’ll need a specific set of hardware and software components:

    • Rooted Android Device: Absolute necessity for system-level access.
    • Custom Kernel with Btrfs Support: Your device’s kernel must be compiled with Btrfs support enabled. Many custom ROMs or kernels like LineageOS often include this, but you may need to verify or even compile your own.
    • OTG (On-The-Go) Adapter: To connect external USB drives to your Android device.
    • Multiple USB Storage Devices: At least two drives (USB flash drives or external HDDs/SSDs) are required for any RAID configuration. Ensure they are of similar size for optimal performance and capacity utilization.
    • Powered USB Hub: If using multiple power-hungry USB drives, a powered hub is crucial to prevent power issues and ensure stable operation.
    • BusyBox: Provides essential core utilities like `fdisk`, `mount`, and `ls` that are often missing or stripped-down in Android’s default shell environment.
    • Btrfs-progs Binary: The Btrfs userspace utilities (`mkfs.btrfs`, `btrfs`, `btrfsck`, etc.) compiled for ARM architecture. These might not be readily available for every Android device and may require cross-compilation.
    • Terminal Emulator App: Such as Termux or any other app that provides root shell access.

    Obtaining Btrfs-progs for Android (ARM)

    This is often the trickiest part. You have a few options:

    1. Search for pre-compiled binaries: Look on XDA-Developers forums or similar communities for `btrfs-progs` binaries compiled for ARM Android.
    2. Cross-compile yourself: If you have a Linux development environment, you can download the Btrfs-progs source code and cross-compile it for ARM. This involves setting up an ARM toolchain and using `configure –host=arm-linux-gnueabi` followed by `make` and `make install`.

    Once obtained, place the `btrfs` and `mkfs.btrfs` executables (and any others you need) into a directory accessible from your PATH (e.g., `/data/local/bin` or within your BusyBox installation’s path) and ensure they have execute permissions (`chmod +x`).

    Step-by-Step: Building Your Btrfs RAID Array

    Before proceeding, ensure all your USB drives are connected via the OTG adapter and powered USB hub. Verify they are detected by your Android device (e.g., in `dmesg` or `/proc/partitions`).

    1. Partitioning the USB Drives

    We’ll prepare each drive with a single partition, formatted as Linux filesystem (type 83). For simplicity, we’ll assume your drives appear as `/dev/block/sdb` and `/dev/block/sdc` (adjust names based on your device).

    su# parted /dev/block/sdb(parted) mklabel gpt(parted) mkpart primary 0% 100%(parted) quitsu# parted /dev/block/sdc(parted) mklabel gpt(parted) mkpart primary 0% 100%(parted) quit

    Note: `fdisk` can also be used, but `parted` is more robust for larger disks and GPT tables. After partitioning, the new partitions will likely be `/dev/block/sdb1` and `/dev/block/sdc1`.

    2. Creating the Btrfs RAID Array

    Now, we’ll create the Btrfs filesystem with your desired RAID level. For this example, we’ll create a RAID 1 (mirroring) array for data redundancy.

    su# mkfs.btrfs -d raid1 -m raid1 /dev/block/sdb1 /dev/block/sdc1

    Explanation:

    • `mkfs.btrfs`: The command to create a Btrfs filesystem.
    • `-d raid1`: Specifies RAID 1 for data chunks.
    • `-m raid1`: Specifies RAID 1 for metadata chunks.
    • `/dev/block/sdb1 /dev/block/sdc1`: The partitions that will form the array.

    For RAID 0 (striping), you would use `-d raid0 -m single` (metadata is often best kept on a single device or mirrored, even with RAID 0 data).

    # Example for RAID 0su# mkfs.btrfs -d raid0 -m single /dev/block/sdb1 /dev/block/sdc1

    The `mkfs.btrfs` command will take some time, depending on the size of your drives. Upon completion, it will display information about your new filesystem, including its UUID.

    3. Mounting the Btrfs RAID Array

    Create a mount point and mount your newly created array.

    su# mkdir /mnt/btrfs_raidsu# mount -t btrfs /dev/block/sdb1 /mnt/btrfs_raid

    You only need to specify one device for mounting; Btrfs will automatically detect all devices in the array. Verify it’s mounted correctly:

    su# df -h /mnt/btrfs_raid

    You should see your Btrfs filesystem listed.

    4. Basic Btrfs Operations (Post-Setup)

    Check Filesystem Status

    You can check the status of your Btrfs array and its devices:

    su# btrfs filesystem show /mnt/btrfs_raid

    Create a Subvolume

    Subvolumes are a key feature of Btrfs, allowing for flexible filesystem layouts and snapshotting.

    su# btrfs subvolume create /mnt/btrfs_raid/mysubvolume

    Take a Snapshot

    Snapshots are point-in-time copies of your subvolume, perfect for backups or testing changes without affecting your live data.

    su# btrfs subvolume snapshot -r /mnt/btrfs_raid/mysubvolume /mnt/btrfs_raid/mysubvolume_snapshot_YYYYMMDD

    Add or Remove Devices (Advanced)

    Btrfs allows online addition or removal of devices, a powerful feature for expanding or repairing your array. For example, to add a new device `/dev/block/sdd1` to a RAID 1 array:

    su# btrfs device add /dev/block/sdd1 /mnt/btrfs_raidsu# btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt/btrfs_raid

    The `balance` command will redistribute data to incorporate the new device. This process can be lengthy.

    Important Considerations and Best Practices

    • Power Stability: Unstable power to your USB drives can lead to filesystem corruption. Always use a reliable, powered USB hub.
    • Kernel Support: Ensure your custom kernel is stable and truly supports Btrfs. Experimental or buggy support can lead to data loss.
    • Backup Your Data: Even with RAID, backups are paramount. RAID provides redundancy against drive failure, not against accidental deletion or filesystem corruption.
    • Performance Expectations: While RAID can boost performance, the overhead of USB, the Android OS, and potentially slower external drives will limit peak performance compared to a dedicated desktop or server.
    • Safety Unmount: Always unmount your Btrfs array cleanly before disconnecting drives:su# umount /mnt/btrfs_raid

    Conclusion

    Building a Btrfs RAID array on Android is a testament to the versatility and power of open-source software and custom Android development. While requiring significant technical prowess and careful execution, the reward is an incredibly robust, high-performance, and feature-rich storage solution that pushes the boundaries of what’s possible on a mobile device. Embrace the challenge, and unlock a new dimension of data management on your Android workstation.

  • Beyond TWRP: Using Btrfs Snapshots for Lightning-Fast Android OS Experimentation & Rollbacks

    Introduction: The Limitations of Traditional Android Recovery

    For years, Android enthusiasts have relied on custom recoveries like TWRP to flash custom ROMs, kernels, and mods. While invaluable, TWRP’s backup and restore functionality, typically based on block-level image backups, can be slow and storage-intensive, especially for large data partitions. A full data restore can take significant time, hindering rapid experimentation and iterative development.

    Enter Btrfs (B-tree file system), a modern copy-on-write (CoW) file system for Linux, offering features that redefine how we manage data, including lightning-fast snapshots, subvolumes, and integrity checks. This article will guide you through leveraging Btrfs snapshots on your Android device to create instant backups and rollbacks, transforming your experimentation workflow.

    Why Btrfs is a Game Changer for Android Customization

    Btrfs introduces several features that make it inherently superior to traditional file systems like ext4 for system-level experimentation:

    • Copy-on-Write (CoW): Data is never overwritten in place. Instead, new data is written to a fresh block, and metadata pointers are updated. This mechanism is fundamental to efficient snapshots and data integrity.
    • Snapshots: Btrfs snapshots are not full copies; they are simply a new set of metadata pointers to existing data blocks. This means snapshots are created almost instantly and consume very little space initially, only growing as the original data (or the snapshot itself) changes.
    • Subvolumes: Subvolumes are independently mountable file system trees. You can think of them as flexible, isolated directories that can be managed, snapshotted, and rolled back independently, even within the same Btrfs partition.
    • Checksums: Btrfs maintains checksums for both data and metadata, ensuring data integrity against silent corruption.

    For Android users, these features translate to:

    • Instant Backups: Create a ‘clean’ state snapshot of your OS or data in seconds.
    • Rapid Rollbacks: Revert to any previous snapshot almost instantly, without lengthy restore operations.
    • Efficient Storage: Snapshots are space-efficient, only storing differences, allowing for many more recovery points.

    Prerequisites for Btrfs on Android

    Before diving in, ensure you meet the following requirements:

    1. Rooted Android Device: Magisk or similar root solution is necessary for shell access and system modifications.
    2. Custom Recovery (e.g., TWRP): Essential for initial partition formatting and flashing Btrfs-compatible kernels or ROMs.
    3. Btrfs-Compatible Kernel: Your device’s kernel *must* have Btrfs support compiled in. Many custom ROMs or kernels offer this. If not, you might need to compile your own kernel or find one that does.
    4. Linux Environment (PC): A Linux machine (physical or VM) is highly recommended for preparing partition images, executing Btrfs commands, and using adb.
    5. Basic ADB & Fastboot Knowledge: Familiarity with these tools is crucial for interacting with your device.
    6. Backup Your Data: ALWAYS create a full backup of your device using TWRP *before* proceeding. Data loss is a risk.

    Setting Up Btrfs on Your Android Data Partition

    Converting your entire `/system` partition to Btrfs is complex and highly device/ROM-specific, often requiring a custom GSI or a deeply modified ROM. A more practical and safer approach for experimentation is to convert your `/data` partition to Btrfs. This allows you to manage user apps, settings, and internal storage with snapshots.

    Step 1: Backup Your Current Data

    Boot into TWRP. Create a full backup of your Data partition to external storage (SD card or USB OTG). This is your safety net.

    Step 2: Wipe the Data Partition

    In TWRP, go to Wipe > Advanced Wipe. Select Data and confirm the wipe. This will erase all user data, apps, and internal storage.

    Step 3: Format Data to Btrfs

    After wiping, you need to format the partition with Btrfs. In TWRP, go to Wipe > Format Data. Type yes to confirm. Then, go to Advanced Wipe > Repair or Change File System > Data. Select Change File System and choose BTRFS. Confirm the change.

    Alternatively, if TWRP doesn’t offer direct Btrfs formatting, you can do it via adb shell after booting into TWRP:

    adb shell
    umount /data
    mkfs.btrfs -f /dev/block/by-name/userdata # Replace 'userdata' with your actual data partition block device
    mount /data

    You can identify your data partition using ls -l /dev/block/by-name/ or checking TWRP’s mount points.

    Step 4: Create Initial Subvolumes and Snapshots

    After formatting, you’ll want to create a base subvolume for your data and then a clean snapshot. Reboot your device into Android (it might take longer for the first boot as it sets up). Once booted and setup, reboot to recovery again.

    Connect to adb shell while in TWRP:

    adb shell
    mount /dev/block/by-name/userdata /mnt # Mount your Btrfs data partition
    btrfs subvolume create /mnt/data # Create the 'data' subvolume where Android will store its files
    btrfs subvolume snapshot -r /mnt/data /mnt/.snapshots/base_clean # Create a read-only snapshot of the pristine state

    The -r flag creates a read-only snapshot, which is ideal for a ‘base clean’ state as it prevents accidental modification. Android will automatically mount the /data subvolume if it’s the default or configured as such.

    The Power of Btrfs Snapshots: Experimentation & Rollbacks

    Now that your data partition is Btrfs-enabled and you have a base snapshot, let’s explore how to use it for experimentation.

    Scenario: Installing a Risky Magisk Module

    1. Create a Pre-Experiment Snapshot: Before installing a module, create a writable snapshot of your current /data state. Boot into recovery (TWRP) and connect via adb shell.

    adb shell
    mount /dev/block/by-name/userdata /mnt
    btrfs subvolume snapshot /mnt/data /mnt/.snapshots/before_module_install
    umount /mnt

    2. Reboot and Experiment: Reboot to Android. Install your Magisk module, tweak system settings, or flash a small mod. If everything works, great! If not, proceed to the rollback.

    Performing a Rollback

    If your experiment causes bootloops, instability, or unwanted changes, rolling back is incredibly fast:

    1. Boot into Recovery: Go back to TWRP.

    2. Mount Btrfs Partition: Connect via adb shell and mount your data partition.

    adb shell
    mount /dev/block/by-name/userdata /mnt

    3. Delete Current Data Subvolume: Remove the problematic /data subvolume.

    btrfs subvolume delete /mnt/data

    4. Restore from Snapshot: Create a new /data subvolume from your chosen snapshot (e.g., before_module_install).

    btrfs subvolume snapshot /mnt/.snapshots/before_module_install /mnt/data
    umount /mnt

    5. Reboot: Your device will now boot into the state captured by the before_module_install snapshot, undoing all changes made during your experiment.

    Listing and Deleting Snapshots

    You can manage your snapshots from recovery:

    adb shell
    mount /dev/block/by-name/userdata /mnt
    btrfs subvolume list -t -o /mnt
    btrfs subvolume delete /mnt/.snapshots/old_snapshot_name
    umount /mnt

    The list command shows all subvolumes and snapshots within your Btrfs partition.

    Advanced Btrfs Concepts for Android

    • Read-Only Snapshots for Base Images: Always keep a read-only snapshot of your
  • RE Lab: Deploying a ZFS-Backed High-Performance Android Emulator Environment on Linux

    Introduction: The Power of ZFS for Android Emulation

    Android emulation environments, especially for reverse engineering (RE) labs or intensive development, demand robust performance and flexible state management. Traditional filesystems often struggle with the I/O demands and the need for frequent state rollbacks. This is where ZFS on Linux (ZoL) shines. By leveraging ZFS’s copy-on-write architecture, snapshots, data integrity features, and adaptive caching, we can create an unparalleled Android emulator setup that offers superior performance, instant rollbacks, and efficient storage management.

    This guide will walk you through deploying and tuning a ZFS-backed environment specifically optimized for Android emulators, focusing on creating dedicated datasets, configuring performance-critical properties, and utilizing ZFS’s advanced features for a truly high-performance and resilient RE lab setup.

    Prerequisites and System Preparation

    Before diving into ZFS configurations, ensure your Linux system is adequately prepared. While this guide assumes ZFS on Linux is already installed and a root filesystem or dedicated ZFS pool is operational, we’ll focus on creating and tuning specific datasets for our emulator needs.

    Hardware Requirements:

    • RAM: Minimum 16GB, 32GB or more highly recommended. ZFS thrives on RAM for its Adaptive Replacement Cache (ARC).
    • CPU: Modern multi-core CPU with virtualization extensions (Intel VT-x/AMD-V) enabled in BIOS/UEFI.
    • Storage: Fast SSD or NVMe drive for your ZFS pool. Mechanical drives are not recommended for emulator performance.

    Software Requirements:

    • ZFS on Linux: Ensure ZoL is installed and your pool is healthy.
    • KVM: Kernel-based Virtual Machine must be enabled. Verify with kvm-ok.
    • Android Studio: Or at least the Android SDK, platform tools, and emulator components.

    First, verify your ZFS pool’s health:

    sudo zpool status

    This command should report your pool as healthy. If you need to create a new pool, a basic example would be (replace `/dev/sdX` with your actual device):

    sudo zpool create rpool /dev/nvme0n1

    For production or critical environments, consider redundancy (e.g., `mirror` or `raidz`).

    Architecting the ZFS Datasets for Emulation

    A well-structured ZFS dataset hierarchy is crucial for manageability and performance. We’ll create a dedicated dataset for our Android emulator images and configurations.

    Creating the Base Dataset

    We’ll create a new ZFS dataset specifically for our Android emulator files. We’ll set performance-oriented properties during creation or afterward.

    sudo zfs create -o mountpoint=/opt/android-emulators rpool/android/emulators

    Now, let’s set key ZFS properties for optimal emulator performance:

    • compression=zstd (or lz4): ZSTD offers an excellent balance of compression ratio and speed, often outperforming LZ4 while still being very fast. This reduces I/O and storage footprint.
    • recordsize=128K: The default 128KB is often suitable for large, block-oriented files like emulator disk images. Avoid smaller record sizes which can lead to fragmentation. Larger record sizes (e.g., 256K) might be beneficial for extremely large, mostly sequential files, but 128K is a good default.
    • atime=off: Disables updating the access time of files, reducing metadata writes and improving I/O performance.
    • primarycache=all: (Default) Ensures data and metadata are cached in the ARC, maximizing the benefits of your system’s RAM.

    Apply these properties:

    sudo zfs set compression=zstd rpool/android/emulatorssudo zfs set atime=off rpool/android/emulatorssudo zfs set recordsize=128K rpool/android/emulators # If not already 128K

    Installing Android Studio and Configuring Emulators

    Install Android Studio as you normally would. Download the tarball from the official website, extract it, and run the `studio.sh` script. Proceed with the standard installation and SDK setup.

    Creating a ZFS-Backed Android Virtual Device (AVD)

    By default, Android Studio stores AVDs in `~/.android/avd`. To leverage our ZFS dataset, we can either create the AVDs directly in the ZFS mountpoint or move existing ones and use a symlink.

    Option 1: Create AVD directly in ZFS dataset (recommended for new setups)

    When you go to create a new AVD in Android Studio’s AVD Manager, in the

  • Advanced Btrfs Subvolume Management on Android: Optimizing Filesystem Layout & Storage Efficiency

    Introduction: Unlocking Btrfs Power on Android

    While Android typically relies on ext4 or F2FS for its filesystem, the robust features of Btrfs offer unparalleled flexibility and resilience for advanced users. Beyond basic partition formatting, Btrfs subvolumes, snapshots, and send/receive capabilities can revolutionize how you manage data, perform system upgrades, and even safeguard your device against unforeseen issues. This guide delves into advanced Btrfs subvolume management, demonstrating how to optimize your Android device’s filesystem layout for superior storage efficiency and data control.

    Prerequisites for Advanced Btrfs on Android

    Implementing advanced Btrfs features on Android requires a foundational setup. Ensure you have the following:

    • Rooted Android Device: Essential for shell access and filesystem modifications.
    • Custom Kernel/ROM with Btrfs Support: Your kernel must be compiled with Btrfs support enabled. Many custom ROMs or kernels for specific devices offer this.
    • ADB (Android Debug Bridge) & Fastboot: Installed and configured on your computer for device interaction.
    • Btrfs-progs Utilities: The btrfs command-line tools must be available on your Android device. These are often included in custom ROMs or can be statically compiled and pushed to /system/xbin.
    • Basic Linux Command-Line Knowledge: Familiarity with commands like mount, ls, mkdir, and file permissions.

    Understanding Btrfs Subvolumes

    Unlike traditional directories, Btrfs subvolumes are independent mountable filesystem trees. They can be snapshotted, replicated, and have different mount options applied. This distinction is crucial for advanced management:

    • Isolation: A subvolume acts like a separate partition but shares the same underlying block device.
    • Flexibility: Mount different subvolumes at different points in your Android directory hierarchy.
    • Snapshots: Create read-only or read-write copies of a subvolume instantly.

    Setting Up a Btrfs Filesystem

    Before advanced subvolume management, you need a Btrfs partition. We’ll assume your /data partition is already Btrfs. If not, converting it requires backing up data, flashing a custom kernel with Btrfs support, and reformatting. This process is device-specific and beyond this guide’s scope, but generally involves:

    adb reboot bootloaderfastboot erase userdatafastboot format:btrfs userdata # Or flash a Btrfs-ready custom ROMimageadb reboot

    Advanced Subvolume Management Techniques

    Creating and Managing Subvolumes

    Once you have a Btrfs filesystem, you can create subvolumes. Let’s assume your Btrfs filesystem is mounted at /data.

    Creating Subvolumes:

    We’ll create subvolumes for common Android data paths:

    adb shell# Make sure /data is mounted (it should be by default)su -c 'btrfs subvolume create /data/media_rw/0'su -c 'btrfs subvolume create /data/app_sub'su -c 'btrfs subvolume create /data/dalvik_cache_sub'su -c 'btrfs subvolume list /data'

    The last command lists all subvolumes and their IDs.

    Mounting Subvolumes:

    To use these, you’d typically modify your Android’s init.rc or a device-specific mount script to mount them at their desired locations. For instance, to mount /data/media_rw/0 to /data/media (the user storage path):

    # Example entry for init.rc or similar mount scriptmount btrfs /dev/block/by-name/userdata /data rw,compress=zstd,ssd,commit=10subvol=/data # Mount the default root subvoluemount btrfs /dev/block/by-name/userdata /data/media rw,compress=zstd,ssd,commit=10subvol=/data/media_rw/0 # Mount the user media subvolume

    Remember, the exact block device path might vary (e.g., /dev/block/dm-0 or a specific /dev/block/mmcblk0pX).

    Btrfs Snapshots: Instant Rollbacks and Backups

    Snapshots are perhaps the most powerful feature. They provide a point-in-time copy of a subvolume with minimal overhead.

    Creating a Read-Only Snapshot:

    Ideal before system updates or risky modifications.

    adb shellsu -c 'btrfs subvolume snapshot -r /data/media_rw/0 /data/media_rw/0_backup_20231027'

    Creating a Read-Write Snapshot:

    Useful for testing changes or creating a working copy you can modify without affecting the original.

    adb shellsu -c 'btrfs subvolume snapshot /data/app_sub /data/app_sub_test_env'

    Rolling Back a Snapshot:

    If something goes wrong, you can quickly revert. First, delete the current subvolume, then rename the snapshot.

    adb shellsu -c 'btrfs subvolume delete /data/media_rw/0' # DANGER: This deletes the current data!su -c 'mv /data/media_rw/0_backup_20231027 /data/media_rw/0'

    You would then reboot, and the system would use the old subvolume.

    Btrfs Send/Receive: Incremental Backups and Replication

    The send/receive feature allows efficient streaming of subvolume changes. It’s perfect for incremental backups to an external storage device or another Linux system.

    Example: Backing up /data/media_rw/0 to an SD Card

    First, create a read-only snapshot of your source subvolume:

    adb shellsu -c 'btrfs subvolume snapshot -r /data/media_rw/0 /data/media_rw/0_snapshot_for_send'

    Mount your external SD card (assuming it’s formatted as Btrfs) to a temporary location, e.g., /mnt/sdcard_btrfs.

    adb shellsu -c 'mount -t btrfs /dev/block/mmcblk1p1 /mnt/sdcard_btrfs' # Adjust device path!

    Now, send the snapshot:

    adb shellsu -c 'btrfs send /data/media_rw/0_snapshot_for_send | btrfs receive /mnt/sdcard_btrfs'

    For incremental backups, you’d take a new snapshot and send the difference from the previous one. This requires both the source and target to have a common parent snapshot.

    # Assuming 'parent_snapshot' exists on both source and targetsu -c 'btrfs subvolume snapshot -r /data/media_rw/0 /data/media_rw/0_new_snapshot'su -c 'btrfs send -p /data/media_rw/0_snapshot_for_send /data/media_rw/0_new_snapshot | btrfs receive /mnt/sdcard_btrfs'

    Remember to delete old snapshots after successful backups to reclaim space.

    Btrfs RAID Levels (for Multi-Device Setups)

    While less common for internal Android storage, Btrfs supports RAID0, RAID1, RAID10, RAID5, and RAID6 across multiple devices. This is incredibly useful if you’re using multiple SD cards or USB OTG drives for extended storage.

    Adding a Device to an Existing Btrfs Filesystem:

    Let’s say you have a Btrfs filesystem on /dev/block/mmcblk0p1 and want to add /dev/block/sdb1 (a USB drive) for redundancy (RAID1).

    adb shellsu -c 'btrfs device add /dev/block/sdb1 /data' # Add the new device

    Converting Data to RAID1:

    After adding, you need to balance the data and metadata to the desired RAID level.

    adb shellsu -c 'btrfs balance start -dconvert=raid1 -mconvert=raid1 /data'

    This process can take a long time, depending on the data size. You can monitor its progress with btrfs balance status /data.

    Optimizing Filesystem Layout for Android

    Using subvolumes, you can create a more modular and efficient Android setup:

    • Separate User Data: /data/media_rw/0 as a subvolume for user files (photos, downloads).
    • App Installations: /data/app_sub for installed apps.
    • Dalvik/ART Cache: /data/dalvik_cache_sub for compiled app caches.
    • System Overlay: For advanced users, a subvolume for system overlay (e.g., in a systemless root setup).

    This allows you to:

    • Take independent snapshots of user data for backup, separate from app data.
    • Easily wipe app data or cache by deleting and recreating their respective subvolumes, without affecting user media.
    • Apply different compression or SSD options per subvolume if your Btrfs implementation allows.

    Best Practices and Considerations

    • Compression: Use compress=zstd or compress=lzo as a mount option for better storage efficiency and potentially faster I/O (especially for SSD/eMMC).
    • SSD/eMMC Optimizations: Always use the ssd mount option. Consider noatime for reduced write amplification.
    • Regular Scrubbing: Periodically run btrfs scrub start /data to check for and correct data checksum errors.
    • Kernel Compatibility: Ensure your kernel is recent enough for stable Btrfs performance and features.
    • Backup Regularly: While Btrfs is robust, it’s not a substitute for external backups. Use btrfs send/receive to an external drive.
    • Space Management: Monitor Btrfs space usage with btrfs filesystem df /data.

    Conclusion

    Advanced Btrfs subvolume management transforms your Android device into a highly resilient and customizable platform. From instant system rollbacks with snapshots to efficient incremental backups with send/receive, and the potential for multi-device RAID, Btrfs offers features far beyond standard filesystems. While requiring a deeper understanding of Linux and Android internals, the benefits in terms of data integrity, system flexibility, and storage optimization are substantial for the power user.

  • Btrfs Snapshots Not Working on Android? Expert Troubleshooting & Fixes for Corrupted Systems

    Introduction: Navigating Btrfs Snapshots on Android

    Btrfs, the Copy-on-Write (CoW) filesystem, offers advanced features like snapshots, subvolumes, and integrity checks that are incredibly powerful for Linux systems. For Android enthusiasts and power users who venture into custom ROMs, advanced kernels, or even `chroot` environments, leveraging Btrfs on storage partitions (most commonly `/data`) can provide unparalleled flexibility for backups, system rollback, and experimentation. However, despite its advantages, Btrfs on Android can be a challenging beast, especially when snapshots mysteriously fail or your system exhibits corruption. This expert guide dives deep into troubleshooting Btrfs snapshot issues on Android, offering practical solutions for common problems, including system corruption.

    Understanding Btrfs on Android and Snapshot Mechanics

    Before troubleshooting, it’s crucial to grasp how Btrfs operates, especially within the Android ecosystem. Btrfs treats entire filesystems as a collection of subvolumes. A snapshot is essentially a read-only or read-write copy of a subvolume at a specific point in time. Because of CoW, a snapshot initially consumes almost no extra space; it only stores differences as the original subvolume changes. This non-destructive nature makes snapshots ideal for atomic updates or experimental changes.

    On Android, Btrfs is typically used for the `/data` partition, replacing `ext4` or `f2fs`. For Btrfs features to work correctly, your custom kernel must be compiled with robust Btrfs support, and you often need a compatible set of `btrfs-progs` binaries (often built for ARM/ARM64) available in your recovery environment or `PATH` after rooting.

    Common Causes for Btrfs Snapshot Failures

    • Kernel Support Deficiency: Outdated or improperly compiled kernels may lack essential Btrfs features or modules.
    • Filesystem Corruption: Improper shutdowns, power loss, or hardware issues can corrupt the Btrfs filesystem, rendering snapshots unmanageable.
    • Incorrect Subvolume Setup: If the root of your `/data` is not a proper subvolume, or if you’re trying to snapshot something incorrectly structured.
    • Insufficient Space: While CoW is efficient, Btrfs still needs free space for metadata and new data blocks.
    • Permissions/SELinux: Android’s stringent security contexts (SELinux) or file permissions can block Btrfs operations.
    • Toolchain Limitations: Stock Android `toybox` or minimalistic `busybox` often lack full `btrfs-progs` functionality.

    Expert Troubleshooting Steps & Fixes

    1. Verify Btrfs Kernel Support

    First, ensure your kernel actually supports Btrfs and its features. This usually requires root access or a custom recovery shell.

    adb shellsu -c "grep BTRFS /proc/filesystems"

    You should see `btrfs` listed. If not, your kernel might not have full Btrfs support compiled in. You might also want to check for loaded modules:

    adb shellsu -c "lsmod | grep btrfs"

    If support is missing, you’ll need to flash a kernel that explicitly includes robust Btrfs support.

    2. Check Filesystem Health for Corruption

    Filesystem corruption is a prime suspect for snapshot failures. You’ll typically need to boot into a custom recovery (like TWRP) to unmount `/data` and perform checks.

    adb shell# Assuming /dev/block/by-name/userdata is your /data partition (verify with lsblk or mount)umount /data# Initiate a scrub to check data and metadata integritybtrfs scrub start /dev/block/by-name/userdata# Check scrub statusbtrfs scrub status /dev/block/by-name/userdata

    A scrub is non-destructive and detects errors. If errors are found, it often indicates underlying corruption. For severe corruption that prevents mounting or `scrub` from running, you might need more drastic measures.

    3. List and Inspect Subvolumes/Snapshots

    Ensure your subvolume structure is as expected and existing snapshots are visible.

    adb shellsu -c "btrfs subvolume list -t /data"

    This command lists all subvolumes and snapshots within your `/data` partition, including their IDs. Look for any unexpected entries or missing subvolumes.

    4. Attempt Manual Snapshot Creation

    Try creating a simple snapshot manually to isolate if the issue is with your script/tool or Btrfs itself.

    adb shellsu -c "btrfs subvolume snapshot /data /data/.snapshots/my_test_snapshot_$(date +%Y%m%d_%H%M%S)"

    If this fails, examine the error message carefully. Common errors include