Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63de76b5 authored by Jooyung Han's avatar Jooyung Han
Browse files

PackageCacher: cache key for block-device APEX

PackageCacher manages its cache based on package filename. When an APEX
is mounted from a device-mapper block device, it creates a cache with a
block device filename (e.g. dm-17), which is not stable. The number can
change even if the APEX itsef is not changed.

Instead, PackageCacher can use the device mapper name for its cache key
if a given package is a device mapper block device because the device
name is stable across reboots. The device name can be read from sysfs
(e.g.  /sys/block/dm-17/dm/name).

In this change, PackageCacher uses a device-mapper name as a cache key
if a given package is a device-mapper device.

Bug: 427589794
Flag: com.android.apex.flags.mount_before_data
Test: adb install <APEX> && reboot
Test: adb shell ls /data/system/package_cache/{hash}
Change-Id: Iea9cdc5a4128d7c1f7440737b419ed9e2252d009
parent 845a67a2
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -75,11 +75,30 @@ public class PackageCacher implements IPackageCacher {
     * Returns the cache key for a specified {@code packageFile} and {@code flags}.
     */
    private String getCacheKey(File packageFile, int flags) {
        StringBuilder sb = new StringBuilder(packageFile.getName());
        String name = packageFile.getName();
        String absPath = packageFile.getAbsolutePath();

        // In case the package is an APEX which is from a device-mapper block
        // device created by apexd, the filename (dm-NN) can be different on
        // each boot. Hence, we use the device-mapper name instead, which is
        // stable across reboots.
        if (absPath.startsWith("/dev/block/dm-")) {
            try {
                name = IoUtils.readFileAsString("/sys/block/" + name + "/dm/name").trim();
                // The device name represents the file. No need to append the hash of the full path.
                absPath = null;
            } catch (IOException e) {
                Slog.w("Error while reading device name of " + name, e);
            }
        }

        StringBuilder sb = new StringBuilder(name);
        sb.append('-');
        sb.append(flags);
        if (absPath != null) {
            sb.append('-');
        sb.append(packageFile.getAbsolutePath().hashCode());
            sb.append(absPath.hashCode());
        }

        return sb.toString();
    }