Pulled lots of changes from Droidian

This commit is contained in:
Adam Boardman 2023-04-20 13:05:40 +01:00
parent a3b2b084f7
commit 16cedf8595
23 changed files with 285 additions and 299 deletions

6
debian/control vendored
View file

@ -8,7 +8,11 @@ Homepage: https://github.com/gemian/lxc-android
Package: lxc-android
Architecture: all
Depends: lxc, gemian-system, planet-linux-kernel
Depends: lxc,
gemian-system,
planet-linux-kernel,
parse-android-dynparts,
halium-wrappers,
Description: lxc configuration for starting android
.
This package provides the configuration for starting android in lxc

View file

@ -1,3 +1,4 @@
etc/*
usr/*
var/*
lib/*

View file

@ -1,12 +1,22 @@
[Unit]
Description=LXC Android Config and Container Initialization
After=android-rootfs.mount
After=android-mount.service
Wants=android-mount.service
[Service]
Type=forking
ExecStart=/usr/bin/lxc-start -n android -d -- /init
ExecStartPost=/usr/lib/lxc-android/lxc-android-ready
ExecStop=/usr/bin/lxc-stop -n android -k
Type=notify
NotifyAccess=exec
# Move the actual container start-up as an ExecStartPre.
# While is not-entirely-correct(TM) this allows for the notification
# script to block.
# The container is now started in background, and lxc-android-notify
# has the task to notify systemd when it's ready.
ExecStartPre=/usr/bin/lxc-start -n android -d
ExecStart=/usr/lib/lxc-android/lxc-android-notify
KillMode=mixed
TimeoutStopSec=120s
ExecStop=/usr/lib/lxc-android/lxc-android-stop
Delegate=yes
[Install]
WantedBy=multi-user.target

9
debian/postinst vendored
View file

@ -3,16 +3,9 @@
systemctl disable lxc
systemctl disable lxc-net
systemctl enable android-mount.service
systemctl enable var-lib-lxc-android-rootfs.mount
systemctl enable vendor.mount
systemctl enable system_root.mount
systemctl enable system.mount
systemctl enable mnt-vendor-protect_s.mount
systemctl enable mnt-vendor-protect_f.mount
systemctl enable mnt-vendor-persist.mount
systemctl enable mnt-vendor-nvdata.mount
systemctl enable mnt-vendor-nvcfg.mount
systemctl enable dev-cpuset.mount
systemctl enable config.mount
systemctl enable bind-vendor.service
systemctl enable wlan-module.service

View file

@ -0,0 +1,3 @@
[device]
wifi.scan-rand-mac-address=no

View file

@ -0,0 +1,12 @@
[Unit]
Description=mount android parts
After=systemd-udev-settle.service local-fs.target
Before=lxc-android.service
Wants=systemd-udev-settle.service
[Service]
Type=oneshot
ExecStart=/usr/lib/lxc-android/mount-android
[Install]
RequiredBy=local-fs.target

View file

@ -1,6 +1,6 @@
[Unit]
Description=Bind mount certain files over /vendor
After=vendor.mount
After=android-mount.service
DefaultDependencies=no
[Service]

View file

@ -1,20 +0,0 @@
[Unit]
Description=Droid mount for /dev/cpuset
Before=local-fs.target systemd-modules-load.service
[Mount]
What=none
Where=/dev/cpuset
Type=cpuset
Options=nodev,noexec,nosuid
# Options had SELinux context option:
# Default is 90 which makes mount period too long in case of
# errors so drop it down a notch.
TimeoutSec=10
[Install]
WantedBy=local-fs.target
# From ./out/target/product/cosmopda/root/init.rc :
# mount cpuset none /dev/cpuset nodev noexec nosuid

View file

@ -1,20 +0,0 @@
[Unit]
Description=Droid mount for /mnt/vendor/nvcfg
Before=local-fs.target systemd-modules-load.service
[Mount]
What=/dev/disk/by-partlabel/nvcfg
Where=/mnt/vendor/nvcfg
Type=ext4
Options=noatime,nosuid,nodev,noauto_da_alloc,commit=1,nodelalloc
# Options had SELinux context option:
# Default is 90 which makes mount period too long in case of
# errors so drop it down a notch.
TimeoutSec=10
[Install]
WantedBy=local-fs.target
# From ./out/target/product/cosmopda/root/fstab.mt6771 :
# /dev/mmcblk0p6 /mnt/vendor/nvcfg ext4 noatime,nosuid,nodev,noauto_da_alloc,commit=1,nodelalloc wait,check,formattable

View file

@ -1,20 +0,0 @@
[Unit]
Description=Droid mount for /mnt/vendor/nvdata
Before=local-fs.target systemd-modules-load.service
[Mount]
What=/dev/disk/by-partlabel/nvdata
Where=/mnt/vendor/nvdata
Type=ext4
Options=noatime,nosuid,nodev,noauto_da_alloc,discard
# Options had SELinux context option:
# Default is 90 which makes mount period too long in case of
# errors so drop it down a notch.
TimeoutSec=10
[Install]
WantedBy=local-fs.target
# From ./out/target/product/cosmopda/root/fstab.mt6771 :
# /dev/mmcblk0p7 /mnt/vendor/nvdata ext4 noatime,nosuid,nodev,noauto_da_alloc,discard wait,check,formattable

View file

@ -1,20 +0,0 @@
[Unit]
Description=Droid mount for /mnt/vendor/persist
Before=local-fs.target systemd-modules-load.service
[Mount]
What=/dev/disk/by-partlabel/persist
Where=/mnt/vendor/persist
Type=ext4
Options=noatime,nosuid,nodev,noauto_da_alloc,commit=1,nodelalloc
# Options had SELinux context option:
# Default is 90 which makes mount period too long in case of
# errors so drop it down a notch.
TimeoutSec=10
[Install]
WantedBy=local-fs.target
# From ./out/target/product/cosmopda/root/fstab.mt6771 :
# /dev/block/platform/bootdevice/by-name/persist /mnt/vendor/persist ext4 noatime,nosuid,nodev,noauto_da_alloc,commit=1,nodelalloc wait,check,formattable

View file

@ -1,20 +0,0 @@
[Unit]
Description=Droid mount for /mnt/vendor/protect_f
Before=local-fs.target systemd-modules-load.service
[Mount]
What=/dev/disk/by-partlabel/protect1
Where=/mnt/vendor/protect_f
Type=ext4
Options=noatime,nosuid,nodev,noauto_da_alloc,commit=1,nodelalloc
# Options had SELinux context option:
# Default is 90 which makes mount period too long in case of
# errors so drop it down a notch.
TimeoutSec=10
[Install]
WantedBy=local-fs.target
# From ./out/target/product/cosmopda/root/fstab.mt6771 :
# /dev/mmcblk0p9 /mnt/vendor/protect_f ext4 noatime,nosuid,nodev,noauto_da_alloc,commit=1,nodelalloc wait,check,formattable

View file

@ -1,20 +0,0 @@
[Unit]
Description=Droid mount for /mnt/vendor/protect_s
Before=local-fs.target systemd-modules-load.service
[Mount]
What=/dev/disk/by-partlabel/protect2
Where=/mnt/vendor/protect_s
Type=ext4
Options=noatime,nosuid,nodev,noauto_da_alloc,commit=1,nodelalloc
# Options had SELinux context option:
# Default is 90 which makes mount period too long in case of
# errors so drop it down a notch.
TimeoutSec=10
[Install]
WantedBy=local-fs.target
# From ./out/target/product/cosmopda/root/fstab.mt6771 :
# /dev/mmcblk0p10 /mnt/vendor/protect_s ext4 noatime,nosuid,nodev,noauto_da_alloc,commit=1,nodelalloc wait,check,formattable

View file

@ -1,20 +0,0 @@
[Unit]
Description=Droid mount for /system_root
Before=local-fs.target systemd-modules-load.service
[Mount]
What=/dev/disk/by-partlabel/system
Where=/system_root
Type=ext4
Options=ro
# Options had SELinux context option:
# Default is 90 which makes mount period too long in case of
# errors so drop it down a notch.
TimeoutSec=10
[Install]
WantedBy=local-fs.target
# From ./out/target/product/cosmopda/root/fstab.mt6771 :
# /dev/mmcblk0p33 / ext4 ro wait,verify,recoveryonly

View file

@ -1,20 +0,0 @@
[Unit]
Description=Droid mount for /vendor
Before=local-fs.target systemd-modules-load.service
[Mount]
What=/dev/disk/by-partlabel/vendor
Where=/vendor
Type=ext4
Options=ro
# Options had SELinux context option:
# Default is 90 which makes mount period too long in case of
# errors so drop it down a notch.
TimeoutSec=10
[Install]
WantedBy=local-fs.target
# From ./out/target/product/cosmopda/root/fstab.mt6771 :
# /dev/mmcblk0p32 /vendor ext4 ro wait,verify,recoveryonly

View file

@ -0,0 +1,84 @@
#!/bin/bash
# When this script starts, the container is starting-up.
# On Android 10+ devices, we need to properly replicate APEX bind-mounts
# on the host system.
LXC_ROOTFS="/var/lib/lxc/android/rootfs"
info() {
echo "I: $@"
}
warning() {
echo "W: $@" >&2
}
error() {
echo "E: $@" >&2
exit 1
}
get_source_apex_name() {
NAME="$(echo ${1} | sed -E 's|\.v[0-9]+$||g')"
for choice in ${NAME} ${NAME}.release ${NAME}.debug ${NAME}.current; do
if [ -e "/android/system/apex/${choice}" ]; then
echo "${choice}"
break
fi
done
}
# Get Android container version
ANDROID_SDK_VERSION=$(grep ro.build.version.sdk= ${LXC_ROOTFS}/system/build.prop | cut -d "=" -f2)
if [ $(getconf LONG_BIT) == 32 ]; then
LIBDIR="lib"
else
LIBDIR="lib64"
fi
# Wait for the container
lxc-wait -n android -t 10 -s "RUNNING"
if [ $ANDROID_SDK_VERSION -ge 29 ]; then
# Android >= 10
info "Detected Android 10+ container"
# Wait for apex to show up
HYBRIS_LD_LIBRARY_PATH="/android/system/apex/com.android.runtime/${LIBDIR}/bionic:/android/system/apex/com.android.runtime.release/${LIBDIR}/bionic:/android/system/apex/com.android.runtime.debug/${LIBDIR}/bionic:/android/system/${LIBDIR}" \
WAITFORSERVICE_VALUE="ready" \
/usr/bin/waitforservice apexd.status
info "apexd ready, replicating bind-mounts"
for mpoint in /apex/*; do
# TODO: Actually determine from where the directory has been bind-mounted
# from, and support non-flattened apexes
if [ ! -d "${mpoint}" ] || [[ ${mpoint} == /apex/*@* ]]; then
continue
fi
apex=$(basename ${mpoint})
target="/apex/${apex}"
source_apex=$(get_source_apex_name ${apex})
if [ -z "${source_apex}" ]; then
warning "Unable to finx source apex for apex ${apex}"
continue
fi
source="/android/system/apex/${source_apex}"
if [ -d "${source}" ]; then
info "Replicating bind-mount for apex ${apex}"
mount --bind ${source} ${target}
fi
done
fi
# Notify systemd we're done
systemd-notify --ready --status="Container ready"
# Block on lxc-wait
lxc-wait -n android -s "STOPPED"

View file

@ -1,20 +0,0 @@
#!/bin/sh -e
lxc-wait -n android -s RUNNING -t 30
containerpid="$(lxc-info -n android -p -H)"
if [ -n "$containerpid" ]; then
while true; do
[ -f /proc/$containerpid/root/dev/.coldboot_done ] && break
sleep 0.1
done
# Allow custom properties before announcing that the boot is completed
if [ -f /custom/custom.prop ]; then
while [ ! -e /dev/socket/property_service ]; do sleep 0.1; done
grep "^custom\." /custom/custom.prop | sed 's/=/ /' | while read property value; do
setprop $property $value
done
fi
else
exit 1
fi

View file

@ -0,0 +1,11 @@
#!/bin/sh
/usr/bin/setprop sys.powerctl shutdown
lxc-wait -n android -s "STOPPED" -t 30
# Teardown mapped super partition
if [ -e "/dev/disk/by-partlabel/super" ]; then
dmsetup remove /dev/mapper/dynpart-* || true
fi
exit 0

View file

@ -0,0 +1,5 @@
#!/bin/sh
mkdir -p /dev/cpuset
mount none /dev/cpuset -t cpuset -o nodev,noexec,nosuid
BIND_MOUNT_PATH="/var/lib/lxc/android/rootfs" /usr/sbin/mount-android.sh

View file

@ -1,100 +0,0 @@
#!/bin/sh
set -e
mountpoints="system data factory persist"
syslabels="FACTORYFS APP system SYSTEM"
datalabels="DATAFS UDA userdata USERDATA"
factorylabels="EFS efs"
persistlabels="persist"
mountopts="noatime,nodiratime,errors=remount-ro"
romountopts="ro,${mountopts}"
bindmountopts="ro,bind"
persistopts="rw,nosuid,nodev,relatime,nodelalloc,data=ordered"
if grep -q "^[a-z0-9/]*./system" /etc/fstab || \
grep -q "^[a-z0-9/]*./data" /etc/fstab; then
exit 0
fi
tmpfile=$(mktemp /tmp/fstab.XXX)
cleanup()
{
case $? in
0)
mv $tmpfile /etc/fstab
chmod 644 /etc/fstab
echo "success"
;;
*)
rm -rf $tmpfile
echo "failed"
;;
esac
}
trap cleanup EXIT INT QUIT ILL KILL SEGV TERM
# logging
log=/var/log/lxc-android-boot.log
exec 3>&1 4>&2 >$log 2>&1
# prepare working file
cp /etc/fstab $tmpfile
echo >>$tmpfile
for mount in $mountpoints; do
path=$diskpath
fs="ext4"
part=""
# make sure the mountpoint exists at all
[ -e "/$mount" ] || mkdir -p /$mount
# different options per mountpioint
case $mount in
system)
labels=$syslabels
options=$romountopts
;;
data)
labels=$datalabels
options=$mountopts
;;
factory)
labels=$factorylabels
options=$romountopts
;;
persist)
labels=$persistlabels
options=$persistopts
;;
esac
disk=""
for partname in $labels; do
diskpaths=$(find /dev -type l -name ${partname}|head -1)
for diskpath in $diskpaths; do
disk=$(readlink -f ${diskpath})
[ -b "$disk" ] && break
done
done
case $diskpath in
*EFS)
mount="efs"
;;
esac
if [ -n "$disk" ]; then
echo "# added by lxc-android-boot for /$mount" >>$tmpfile
echo "$disk\t/$mount\t$fs\t$options\t0\t0" >>$tmpfile
fi
done
if grep -q "^[a-z0-9/]*./system" $tmpfile; then
[ -e "/vendor" ] || mkdir -p /vendor
echo "# added by lxc-android-boot for /vendor" >>$tmpfile
echo "/system/vendor\t/vendor\tauto\t$bindmountopts\t0\t0" >>$tmpfile
fi

129
usr/sbin/mount-android.sh Executable file
View file

@ -0,0 +1,129 @@
#!/bin/bash
# On systems with A/B partition layout, current slot is provided via cmdline parameter.
ab_slot_suffix=$(grep -o 'androidboot\.slot_suffix=..' /proc/cmdline | cut -d "=" -f2)
[ ! -z "$ab_slot_suffix" ] && echo "A/B slot system detected! Slot suffix is $ab_slot_suffix"
find_partition_path() {
label=$1
path="/dev/$label"
# In case fstab provides /dev/mmcblk0p* lines
for dir in by-partlabel by-name by-label by-path by-uuid by-partuuid by-id; do
# On A/B systems not all of the partitions are duplicated, so we have to check with and without suffix
if [ -e "/dev/disk/$dir/$label$ab_slot_suffix" ]; then
path="/dev/disk/$dir/$label$ab_slot_suffix"
break
elif [ -e "/dev/disk/$dir/$label" ]; then
path="/dev/disk/$dir/$label"
break
fi
done
echo $path
}
parse_mount_flags() {
org_options="$1"
options=""
for i in $(echo $org_options | tr "," "\n"); do
[[ "$i" =~ "context" ]] && continue
options+=$i","
done
options=${options%?}
echo $options
}
if [ -e "/dev/disk/by-partlabel/super" ]; then
echo "mapping super partition"
dmsetup create --concise "$(parse-android-dynparts /dev/disk/by-partlabel/super)"
fi
echo "checking for vendor mount point"
vendor_images="/userdata/vendor.img /var/lib/lxc/android/vendor.img /dev/mapper/dynpart-vendor /dev/mapper/dynpart-vendor${ab_slot_suffix}"
for image in $vendor_images; do
if [ -e $image ]; then
echo "mounting vendor from $image"
mount $image /vendor -o ro
fi
done
sys_vendor="/sys/firmware/devicetree/base/firmware/android/fstab/vendor"
if [ -e $sys_vendor ] && ! mountpoint -q -- /vendor; then
label=$(cat $sys_vendor/dev | awk -F/ '{print $NF}')
path=$(find_partition_path $label)
[ ! -e "$path" ] && echo "Error vendor not found" && exit
type=$(cat $sys_vendor/type)
options=$(parse_mount_flags $(cat $sys_vendor/mnt_flags))
echo "mounting $path as /vendor"
mount $path /vendor -t $type -o $options
fi
# Bind-mount /vendor if we should. Legacy devices do not have /vendor
# on a separate partition and we should handle that.
if [ -n "${BIND_MOUNT_PATH}" ] && mountpoint -q -- /vendor; then
# Mountpoint, bind-mount. We don't use rbind as we're going
# to go through the fstab anyways.
mount -o bind /vendor "${BIND_MOUNT_PATH}/vendor"
fi
sys_persist="/sys/firmware/devicetree/base/firmware/android/fstab/persist"
if [ -e $sys_persist ]; then
label=$(cat $sys_persist/dev | awk -F/ '{print $NF}')
path=$(find_partition_path $label)
# [ ! -e "$path" ] && echo "Error persist not found" && exit
type=$(cat $sys_persist/type)
options=$(parse_mount_flags $(cat $sys_persist/mnt_flags))
echo "mounting $path as /mnt/vendor/persist"
mount $path /mnt/vendor/persist -t $type -o $options
fi
echo "checking if system overlay exists"
if [ -d "/usr/lib/droid-system-overlay" ]; then
echo "mounting android's system overlay"
mount -t overlay overlay -o lowerdir=/usr/lib/droid-system-overlay:/var/lib/lxc/android/rootfs/system /var/lib/lxc/android/rootfs/system
fi
echo "checking if vendor overlay exists"
if [ -d "/usr/lib/droid-vendor-overlay" ]; then
echo "mounting android's vendor overlay"
mount -t overlay overlay -o lowerdir=/usr/lib/droid-vendor-overlay:/var/lib/lxc/android/rootfs/vendor /var/lib/lxc/android/rootfs/vendor
fi
# Assume there's only one fstab in vendor
fstab=$(ls /vendor/etc/fstab*)
[ -z "$fstab" ] && echo "fstab not found" && exit
echo "checking fstab $fstab for additional mount points"
cat ${fstab} ${EXTRA_FSTAB} | while read line; do
set -- $line
# stop processing if we hit the "#endhalium" comment in the file
echo $1 | egrep -q "^#endhalium" && break
# Skip any unwanted entry
echo $1 | egrep -q "^#" && continue
([ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]) && continue
([ "$2" = "/system" ] || [ "$2" = "/data" ] || [ "$2" = "/" ] \
|| [ "$2" = "auto" ] || [ "$2" = "/vendor" ] || [ "$2" = "none" ] \
|| [ "$2" = "/misc" ]) && continue
([ "$3" = "emmc" ] || [ "$3" = "swap" ] || [ "$3" = "mtd" ]) && continue
label=$(echo $1 | awk -F/ '{print $NF}')
[ -z "$label" ] && continue
echo "checking mount label $label"
path=$(find_partition_path $label)
[ ! -e "$path" ] && continue
mkdir -p $2
echo "mounting $path as $2"
mount $path $2 -t $3 -o $(parse_mount_flags $4)
# Bind mount on rootfs if we should
if [ -n "${BIND_MOUNT_PATH}" ] && [[ ${2} != /mnt/* ]]; then
# /mnt is recursively binded via the LXC configuration
mount -o bind ${2} "${BIND_MOUNT_PATH}/${2}"
fi
done

View file

@ -3,7 +3,7 @@ lxc.net.0.type = none
lxc.rootfs.path = dir:/var/lib/lxc/android/rootfs
lxc.tty.dir =
lxc.tty.dir = lxc
lxc.tty.max = 4
lxc.pty.max = 1024
lxc.arch = arm64
@ -17,8 +17,7 @@ lxc.cap.drop = mac_admin mac_override
lxc.hook.pre-start = /var/lib/lxc/android/pre-start.sh
# This is not needed as we do it manually within the systemd startup
#lxc.init_cmd = /init
lxc.init.cmd = /init
lxc.apparmor.profile = unconfined
lxc.autodev = 0
@ -28,10 +27,13 @@ lxc.hook.post-stop = /usr/share/lxcfs/lxc.reboot.hook
lxc.mount.entry = tmpfs dev tmpfs nosuid 0 0
lxc.mount.entry = /dev/__properties__ dev/__properties__ bind bind,create=dir 0 0
lxc.mount.entry = /dev/binderfs dev/binderfs bind bind,create=dir,optional 0 0
lxc.mount.entry = /dev/socket dev/socket bind bind,create=dir 0 0
lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0
lxc.mount.entry = sys sys sysfs nodev,noexec,nosuid 0 0
#lxc.mount.entry = tmp tmp tmpfs nodev,noexec,nosuid 0 0
lxc.mount.entry = /data data bind bind 0 0
lxc.mount.entry = /vendor vendor bind rbind 0 0
#lxc.mount.entry = /vendor vendor bind rbind 0 0
lxc.mount.entry = /mnt mnt bind rbind 0 0
lxc.mount.entry = /apex apex bind bind,optional 0 0
lxc.mount.entry = /odm odm bind bind,optional 0 0

View file

@ -55,4 +55,16 @@ else
# Halium 9
mkdir -p /dev/__properties__
mkdir -p /dev/socket
# Mount a tmpfs on /apex if we should
if [ -e "/apex" ]; then
mount -t tmpfs tmpfs /apex
fi
# mount binderfs if needed
if [ ! -e /dev/binder ]; then
mkdir -p /dev/binderfs
mount -t binder binder /dev/binderfs -o stats=global
ln -s /dev/binderfs/*binder /dev
fi
fi