Merge changes I16ea9e32,Ib53b5d3e
* changes:
init: make fatal reboot target configurable
init: dump stack when aborting
diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh
index 04422f9..c523893 100755
--- a/fs_mgr/tests/adb-remount-test.sh
+++ b/fs_mgr/tests/adb-remount-test.sh
@@ -33,6 +33,7 @@
## Helper Variables
##
+EMPTY=""
SPACE=" "
# A _real_ embedded tab character
TAB="`echo | tr '\n' '\t'`"
@@ -50,6 +51,9 @@
start_time=`date +%s`
ACTIVE_SLOT=
+ADB_WAIT=3m
+FASTBOOT_WAIT=2m
+
##
## Helper Functions
##
@@ -131,10 +135,30 @@
adb_logcat() {
echo "${RED}[ INFO ]${NORMAL} logcat ${@}" >&2 &&
adb logcat "${@}" </dev/null |
+ tr -d '\r' |
grep -v 'logd : logdr: UID=' |
sed -e '${/------- beginning of kernel/d}' -e 's/^[0-1][0-9]-[0-3][0-9] //'
}
+[ "USAGE: avc_check >/dev/stderr
+
+Returns: worrisome avc violations" ]
+avc_check() {
+ if ! ${overlayfs_supported:-false}; then
+ return
+ fi
+ local L=`adb_logcat -b all -v brief -d \
+ -e 'context=u:object_r:unlabeled:s0' 2>/dev/null |
+ sed -n 's/.*avc: //p' |
+ sort -u`
+ if [ -z "${L}" ]; then
+ return
+ fi
+ echo "${ORANGE}[ WARNING ]${NORMAL} unlabeled sepolicy violations:" >&2
+ echo "${L}" |
+ sed 's/^/ /' >&2
+}
+
[ "USAGE: get_property <prop>
Returns the property value" ]
@@ -173,7 +197,8 @@
Returns: true if the reboot command succeeded" ]
adb_reboot() {
- adb reboot remount-test || true
+ avc_check
+ adb reboot remount-test </dev/null || true
sleep 2
}
@@ -240,10 +265,13 @@
Returns: waits until the device has returned for adb or optional timeout" ]
adb_wait() {
+ local start=`date +%s`
+ local duration=
local ret
if [ -n "${1}" ]; then
USB_DEVICE=`usb_devnum --next`
- echo -n ". . . waiting `format_duration ${1}`" ${ANDROID_SERIAL} ${USB_ADDRESS} ${USB_DEVICE} "${CR}"
+ duration=`format_duration ${1}`
+ echo -n ". . . waiting ${duration}" ${ANDROID_SERIAL} ${USB_ADDRESS} ${USB_DEVICE} "${CR}"
timeout --preserve-status --signal=KILL ${1} adb wait-for-device 2>/dev/null
ret=${?}
echo -n " ${CR}"
@@ -258,9 +286,45 @@
echo "${ORANGE}[ WARNING ]${NORMAL} Active slot changed from ${ACTIVE_SLOT} to ${active_slot}" >&2
fi
fi
+ local end=`date +%s`
+ local diff_time=`expr ${end} - ${start}`
+ local _print_time=${print_time}
+ if [ ${diff_time} -lt 15 ]; then
+ _print_time=false
+ fi
+ diff_time=`format_duration ${diff_time}`
+ if [ "${diff_time}" = "${duration}" ]; then
+ _print_time=false
+ fi
+
+ local reason=
+ if inAdb; then
+ reason=`get_property ro.boot.bootreason`
+ fi
+ case ${reason} in
+ reboot*)
+ reason=
+ ;;
+ ${EMPTY})
+ ;;
+ *)
+ reason=" for boot reason ${reason}"
+ ;;
+ esac
+ if ${_print_time} || [ -n "${reason}" ]; then
+ echo "${BLUE}[ INFO ]${NORMAL} adb wait duration ${diff_time}${reason}"
+ fi >&2
+
return ${ret}
}
+[ "USAGE: adb_user > /dev/stdout
+
+Returns: the adb daemon user" ]
+adb_user() {
+ adb_sh echo '${USER}' </dev/null
+}
+
[ "USAGE: usb_status > stdout 2> stderr
Assumes referenced right after adb_wait or fastboot_wait failued.
@@ -276,7 +340,7 @@
elif inRecovery; then
echo "(In recovery mode)"
elif inAdb; then
- echo "(In adb mode)"
+ echo "(In adb mode `adb_user`)"
else
echo "(USB stack borken for ${USB_ADDRESS})"
USB_DEVICE=`usb_devnum`
@@ -366,17 +430,68 @@
inFastboot || inAdb || inRecovery
}
+wait_for_screen_timeout=900
+[ "USAGE: wait_for_screen [-n] [TIMEOUT]
+
+-n - echo newline at exit
+TIMEOUT - default `format_duration ${wait_for_screen_timeout}`" ]
+wait_for_screen() {
+ exit_function=true
+ if [ X"-n" = X"${1}" ]; then
+ exit_function=echo
+ shift
+ fi
+ timeout=${wait_for_screen_timeout}
+ if [ ${#} -gt 0 ]; then
+ timeout=${1}
+ shift
+ fi
+ counter=0
+ while true; do
+ if inFastboot; then
+ fastboot reboot
+ elif inAdb; then
+ if [ 0 != ${counter} ]; then
+ adb_wait
+ fi
+ if [ -n "`get_property sys.boot.reason`" ]
+ then
+ vals=`get_property |
+ sed -n 's/[[]sys[.]\(boot_completed\|logbootcomplete\)[]]: [[]\([01]\)[]]$/\1=\2/p'`
+ if [ "${vals}" = "`echo boot_completed=1 ; echo logbootcomplete=1`" ]
+ then
+ sleep 1
+ break
+ fi
+ if [ "${vals}" = "`echo logbootcomplete=1 ; echo boot_completed=1`" ]
+ then
+ sleep 1
+ break
+ fi
+ fi
+ fi
+ counter=`expr ${counter} + 1`
+ if [ ${counter} -gt ${timeout} ]; then
+ ${exit_function}
+ echo "ERROR: wait_for_screen() timed out (`format_duration ${timeout}`)" >&2
+ return 1
+ fi
+ sleep 1
+ done
+ ${exit_function}
+}
+
[ "USAGE: adb_root
NB: This can be flakey on devices due to USB state
Returns: true if device in root state" ]
adb_root() {
- [ root != "`adb_sh echo '${USER}' </dev/null`" ] || return 0
+ [ root != "`adb_user`" ] || return 0
adb root >/dev/null </dev/null 2>/dev/null
sleep 2
- adb_wait 2m &&
- [ root = "`adb_sh echo '${USER}' </dev/null`" ]
+ adb_wait ${ADB_WAIT} &&
+ [ root = "`adb_user`" ]
}
[ "USAGE: adb_unroot
@@ -385,11 +500,11 @@
Returns: true if device in un root state" ]
adb_unroot() {
- [ root = "`adb_sh echo '${USER}' </dev/null`" ] || return 0
+ [ root = "`adb_user`" ] || return 0
adb unroot >/dev/null </dev/null 2>/dev/null
sleep 2
- adb_wait 2m &&
- [ root != "`adb_sh echo '${USER}' </dev/null`" ]
+ adb_wait ${ADB_WAIT} &&
+ [ root != "`adb_user`" ]
}
[ "USAGE: fastboot_getvar var expected >/dev/stderr
@@ -540,6 +655,30 @@
return 0
}
+[ "USAGE: EXPECT_NE <lval> <rval> [--warning [message]]
+
+Returns true if lval matches rval" ]
+EXPECT_NE() {
+ local lval="${1}"
+ local rval="${2}"
+ shift 2
+ local error=1
+ local prefix="${RED}[ ERROR ]${NORMAL}"
+ if [ X"${1}" = X"--warning" ]; then
+ prefix="${RED}[ WARNING ]${NORMAL}"
+ error=0
+ shift 1
+ fi
+ if [ X"${rval}" = X"${lval}" ]; then
+ echo "${prefix} did not expect \"${lval}\" ${*}" >&2
+ return ${error}
+ fi
+ if [ -n "${*}" ] ; then
+ echo "${prefix} ok \"${lval}\" not \"${rval}\" ${*}" >&2
+ fi
+ return 0
+}
+
[ "USAGE: check_eq <lval> <rval> [--warning [message]]
Exits if (regex) lval mismatches rval" ]
@@ -555,6 +694,21 @@
die "${@}"
}
+[ "USAGE: check_ne <lval> <rval> [--warning [message]]
+
+Exits if lval matches rval" ]
+check_ne() {
+ local lval="${1}"
+ local rval="${2}"
+ shift 2
+ if [ X"${1}" = X"--warning" ]; then
+ EXPECT_NE "${lval}" "${rval}" ${*}
+ return
+ fi
+ EXPECT_NE "${lval}" "${rval}" ||
+ die "${@}"
+}
+
[ "USAGE: skip_administrative_mounts [data] < /proc/mounts
Filters out all administrative (eg: sysfs) mounts uninteresting to the test" ]
@@ -645,7 +799,7 @@
inRecovery && die "device in recovery mode"
if ! inAdb; then
echo "${ORANGE}[ WARNING ]${NORMAL} device not in adb mode" >&2
- adb_wait 2m
+ adb_wait ${ADB_WAIT}
fi
inAdb || die "specified device not in adb mode"
isDebuggable || die "device not a debug build"
@@ -697,6 +851,8 @@
esac
done
+# If reboot too soon after fresh flash, could trip device update failure logic
+wait_for_screen
# Can we test remount -R command?
overlayfs_supported=true
if [ "orange" = "`get_property ro.boot.verifiedbootstate`" -a \
@@ -705,19 +861,20 @@
${overlayfs_supported} || return 0
inFastboot &&
fastboot reboot &&
- adb_wait 2m
+ adb_wait ${ADB_WAIT}
inAdb &&
adb_root &&
adb enable-verity >/dev/null 2>/dev/null &&
adb_reboot &&
- adb_wait 2m
+ adb_wait ${ADB_WAIT}
}
echo "${GREEN}[ RUN ]${NORMAL} Testing adb shell su root remount -R command" >&2
+ avc_check
adb_su remount -R system </dev/null || true
sleep 2
- adb_wait 2m ||
+ adb_wait ${ADB_WAIT} ||
die "waiting for device after remount -R `usb_status`"
if [ "orange" != "`get_property ro.boot.verifiedbootstate`" -o \
"2" = "`get_property partition.system.verified`" ]; then
@@ -775,7 +932,7 @@
if ${reboot}; then
echo "${ORANGE}[ WARNING ]${NORMAL} rebooting before test" >&2
adb_reboot &&
- adb_wait 2m ||
+ adb_wait ${ADB_WAIT} ||
die "lost device after reboot after wipe `usb_status`"
adb_root ||
die "lost device after elevation to root after wipe `usb_status`"
@@ -840,7 +997,7 @@
echo "${GREEN}[ INFO ]${NORMAL} rebooting as requested" >&2
L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
adb_reboot &&
- adb_wait 2m ||
+ adb_wait ${ADB_WAIT} ||
die "lost device after reboot requested `usb_status`"
adb_root ||
die "lost device after elevation to root `usb_status`"
@@ -881,6 +1038,11 @@
echo "${GREEN}[ RUN ]${NORMAL} remount" >&2
+# Feed log with selinux denials as baseline before overlays
+adb_unroot
+adb_sh find /system /vendor </dev/null >/dev/null 2>/dev/null
+adb_root
+
D=`adb remount 2>&1`
ret=${?}
echo "${D}"
@@ -981,6 +1143,26 @@
B="`adb_cat /vendor/hello`" ||
die "vendor hello"
check_eq "${A}" "${B}" /vendor before reboot
+SYSTEM_DEVT=`adb_sh stat --format=%D /system/hello </dev/null`
+VENDOR_DEVT=`adb_sh stat --format=%D /vendor/hello </dev/null`
+SYSTEM_INO=`adb_sh stat --format=%i /system/hello </dev/null`
+VENDOR_INO=`adb_sh stat --format=%i /vendor/hello </dev/null`
+BASE_SYSTEM_DEVT=`adb_sh stat --format=%D /system/bin/stat </dev/null`
+BASE_VENDOR_DEVT=`adb_sh stat --format=%D /vendor/bin/stat </dev/null`
+check_eq "${SYSTEM_DEVT%[0-9a-fA-F][0-9a-fA-F]}" "${VENDOR_DEVT%[0-9a-fA-F][0-9a-fA-F]}" vendor and system devt
+check_ne "${SYSTEM_INO}" "${VENDOR_INO}" vendor and system inode
+if ${overlayfs_needed}; then
+ check_ne "${SYSTEM_DEVT}" "${BASE_SYSTEM_DEVT}" system devt
+ check_ne "${VENDOR_DEVT}" "${BASE_VENDOR_DEVT}" vendor devt
+else
+ check_eq "${SYSTEM_DEVT}" "${BASE_SYSTEM_DEVT}" system devt
+ check_eq "${VENDOR_DEVT}" "${BASE_VENDOR_DEVT}" vendor devt
+fi
+check_ne "${BASE_SYSTEM_DEVT}" "${BASE_VENDOR_DEVT}" --warning system/vendor devt
+[ -n "${SYSTEM_DEVT%[0-9a-fA-F][0-9a-fA-F]}" ] ||
+ die "system devt ${SYSTEM_DEVT} is major 0"
+[ -n "${VENDOR_DEVT%[0-9a-fA-F][0-9a-fA-F]}" ] ||
+ die "vendor devt ${SYSTEM_DEVT} is major 0"
# Download libc.so, append some gargage, push back, and check if the file
# is updated.
@@ -1004,12 +1186,12 @@
fixup_from_recovery() {
inRecovery || return 1
echo "${ORANGE}[ ERROR ]${NORMAL} Device in recovery" >&2
- adb reboot
- adb_wait 2m
+ adb reboot </dev/null
+ adb_wait ${ADB_WAIT}
}
adb_reboot &&
- adb_wait 2m ||
+ adb_wait ${ADB_WAIT} ||
fixup_from_recovery ||
die "reboot after override content added failed `usb_status`"
@@ -1033,6 +1215,9 @@
B="`adb_cat /vendor/hello 2>&1`"
check_eq "cat: /vendor/hello: Permission denied" "${B}" vendor after reboot w/o root
echo "${GREEN}[ OK ]${NORMAL} /vendor content correct MAC after reboot" >&2
+ # Feed unprivileged log with selinux denials as a result of overlays
+ wait_for_screen
+ adb_sh find /system /vendor </dev/null >/dev/null 2>/dev/null
fi
B="`adb_cat /system/hello`"
check_eq "${A}" "${B}" /system after reboot
@@ -1044,6 +1229,17 @@
check_eq "${A}" "${B}" vendor after reboot
echo "${GREEN}[ OK ]${NORMAL} /vendor content remains after reboot" >&2
+check_eq "${SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/hello </dev/null`" system devt after reboot
+check_eq "${VENDOR_DEVT}" "`adb_sh stat --format=%D /vendor/hello </dev/null`" vendor devt after reboot
+check_eq "${SYSTEM_INO}" "`adb_sh stat --format=%i /system/hello </dev/null`" system inode after reboot
+check_eq "${VENDOR_INO}" "`adb_sh stat --format=%i /vendor/hello </dev/null`" vendor inode after reboot
+check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/bin/stat </dev/null`" base system devt after reboot
+check_eq "${BASE_VENDOR_DEVT}" "`adb_sh stat --format=%D /vendor/bin/stat </dev/null`" base system devt after reboot
+check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/xbin/su </dev/null`" devt for su after reboot
+
+# Feed log with selinux denials as a result of overlays
+adb_sh find /system /vendor </dev/null >/dev/null 2>/dev/null
+
# Check if the updated libc.so is persistent after reboot.
adb_root &&
adb pull /system/lib/bootstrap/libc.so ${tempdir}/libc.so.fromdevice >/dev/null ||
@@ -1073,10 +1269,17 @@
echo "${ORANGE}[ WARNING ]${NORMAL} wrong vendor image, skipping"
elif [ -z "${ANDROID_HOST_OUT}" ]; then
echo "${ORANGE}[ WARNING ]${NORMAL} please run lunch, skipping"
+elif ! (
+ adb_cat /vendor/build.prop |
+ cmp -s ${ANDROID_PRODUCT_OUT}/vendor/build.prop
+ ) >/dev/null 2>/dev/null; then
+ echo "${ORANGE}[ WARNING ]${NORMAL} vendor image signature mismatch, skipping"
else
- adb reboot fastboot ||
+ wait_for_screen
+ avc_check
+ adb reboot fastboot </dev/null ||
die "fastbootd not supported (wrong adb in path?)"
- any_wait 2m &&
+ any_wait ${ADB_WAIT} &&
inFastboot ||
die "reboot into fastboot to flash vendor `usb_status` (bad bootloader?)"
fastboot flash vendor ||
@@ -1117,7 +1320,7 @@
fastboot reboot ||
die "can not reboot out of fastboot"
echo "${ORANGE}[ WARNING ]${NORMAL} adb after fastboot"
- adb_wait 2m ||
+ adb_wait ${ADB_WAIT} ||
fixup_from_recovery ||
die "did not reboot after flash `usb_status`"
if ${overlayfs_needed}; then
@@ -1150,8 +1353,15 @@
check_eq "cat: /vendor/hello: No such file or directory" "${B}" \
--warning vendor content after flash vendor
fi
+
+ check_eq "${SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/hello </dev/null`" system devt after reboot
+ check_eq "${SYSTEM_INO}" "`adb_sh stat --format=%i /system/hello </dev/null`" system inode after reboot
+ check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/bin/stat </dev/null`" base system devt after reboot
+ check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/xbin/su </dev/null`" devt for su after reboot
+
fi
+wait_for_screen
echo "${GREEN}[ RUN ]${NORMAL} remove test content (cleanup)" >&2
T=`adb_date`
@@ -1163,7 +1373,7 @@
echo "${ORANGE}[ WARNING ]${NORMAL} adb remount requires a reboot after partial flash (legacy avb)"
L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
adb_reboot &&
- adb_wait 2m &&
+ adb_wait ${ADB_WAIT} &&
adb_root ||
die "failed to reboot"
T=`adb_date`
@@ -1185,14 +1395,15 @@
echo "${GREEN}[ RUN ]${NORMAL} test fastboot flash to ${scratch_partition} recovery" >&2
- adb reboot fastboot ||
+ avc_check
+ adb reboot fastboot </dev/null ||
die "Reboot into fastbootd"
img=${TMPDIR}/adb-remount-test-${$}.img
cleanup() {
rm ${img}
}
dd if=/dev/zero of=${img} bs=4096 count=16 2>/dev/null &&
- fastboot_wait 2m ||
+ fastboot_wait ${FASTBOOT_WAIT} ||
die "reboot into fastboot `usb_status`"
fastboot flash --force ${scratch_partition} ${img}
err=${?}
@@ -1204,7 +1415,7 @@
die "can not reboot out of fastboot"
[ 0 -eq ${err} ] ||
die "fastboot flash ${scratch_partition}"
- adb_wait 2m &&
+ adb_wait ${ADB_WAIT} &&
adb_root ||
die "did not reboot after flash"
T=`adb_date`
@@ -1214,7 +1425,7 @@
then
echo "${ORANGE}[ WARNING ]${NORMAL} adb disable-verity requires a reboot after partial flash"
adb_reboot &&
- adb_wait 2m &&
+ adb_wait ${ADB_WAIT} &&
adb_root ||
die "failed to reboot"
T=`adb_date`
@@ -1252,12 +1463,12 @@
fastboot --set-active=${ACTIVE_SLOT}
fi
fastboot reboot
- adb_wait 2m
+ adb_wait ${ADB_WAIT}
}
# Prerequisite is a prepped device from above.
adb_reboot &&
- adb_wait 2m ||
+ adb_wait ${ADB_WAIT} ||
fixup_from_fastboot ||
die "lost device after reboot to ro state `usb_status`"
adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null &&
@@ -1270,7 +1481,7 @@
# Prerequisite is a prepped device from above.
adb_reboot &&
- adb_wait 2m ||
+ adb_wait ${ADB_WAIT} ||
fixup_from_fastboot ||
die "lost device after reboot to ro state `usb_status`"
adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null &&
@@ -1291,7 +1502,7 @@
die "/${d}/overlay wipe"
done
adb_reboot &&
- adb_wait 2m ||
+ adb_wait ${ADB_WAIT} ||
fixup_from_fastboot ||
die "lost device after reboot after wipe `usb_status`"
adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null &&
@@ -1309,9 +1520,10 @@
if [ ${err} = 0 ] && ${overlayfs_supported}; then
echo "${GREEN}[ RUN ]${NORMAL} test 'adb remount -R'" >&2
+ avc_check
adb_root &&
adb remount -R &&
- adb_wait 2m ||
+ adb_wait ${ADB_WAIT} ||
die "adb remount -R"
if [ "orange" != "`get_property ro.boot.verifiedbootstate`" -o \
"2" = "`get_property partition.system.verified`" ]; then
diff --git a/init/mount_namespace.cpp b/init/mount_namespace.cpp
index 5305dc7..12144c1 100644
--- a/init/mount_namespace.cpp
+++ b/init/mount_namespace.cpp
@@ -79,6 +79,38 @@
return updatable;
}
+static bool ActivateFlattenedApexesIfPossible() {
+ if (IsRecoveryMode() || IsApexUpdatable()) {
+ return true;
+ }
+
+ constexpr const char kSystemApex[] = "/system/apex";
+ constexpr const char kApexTop[] = "/apex";
+ if (mount(kSystemApex, kApexTop, nullptr, MS_BIND, nullptr) != 0) {
+ PLOG(ERROR) << "Could not bind mount " << kSystemApex << " to " << kApexTop;
+ return false;
+ }
+
+ // Special casing for the runtime APEX
+ constexpr const char kRuntimeApexMountPath[] = "/system/apex/com.android.runtime";
+ static const std::vector<std::string> kRuntimeApexDirNames = {"com.android.runtime.release",
+ "com.android.runtime.debug"};
+ bool success = false;
+ for (const auto& name : kRuntimeApexDirNames) {
+ std::string path = std::string(kSystemApex) + "/" + name;
+ if (access(path.c_str(), F_OK) == 0) {
+ if (mount(path.c_str(), kRuntimeApexMountPath, nullptr, MS_BIND, nullptr) == 0) {
+ success = true;
+ break;
+ }
+ }
+ }
+ if (!success) {
+ PLOG(ERROR) << "Failed to bind mount the runtime APEX to " << kRuntimeApexMountPath;
+ }
+ return success;
+}
+
static android::base::unique_fd bootstrap_ns_fd;
static android::base::unique_fd default_ns_fd;
@@ -129,6 +161,8 @@
default_ns_id = GetMountNamespaceId();
}
+ success &= ActivateFlattenedApexesIfPossible();
+
LOG(INFO) << "SetupMountNamespaces done";
return success;
}
diff --git a/init/service.cpp b/init/service.cpp
index 6887d7b..3e865a7 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -46,6 +46,7 @@
#include "util.h"
#if defined(__ANDROID__)
+#include <ApexProperties.sysprop.h>
#include <android/api-level.h>
#include <sys/system_properties.h>
@@ -372,10 +373,17 @@
return;
}
+#if defined(__ANDROID__)
+ static bool is_apex_updatable = android::sysprop::ApexProperties::updatable().value_or(false);
+#else
+ static bool is_apex_updatable = false;
+#endif
+ const bool is_process_updatable = !pre_apexd_ && is_apex_updatable;
+
// If we crash > 4 times in 4 minutes or before boot_completed,
// reboot into bootloader or set crashing property
boot_clock::time_point now = boot_clock::now();
- if (((flags_ & SVC_CRITICAL) || !pre_apexd_) && !(flags_ & SVC_RESTART)) {
+ if (((flags_ & SVC_CRITICAL) || is_process_updatable) && !(flags_ & SVC_RESTART)) {
bool boot_completed = android::base::GetBoolProperty("sys.boot_completed", false);
if (now < time_crashed_ + 4min || !boot_completed) {
if (++crash_count_ > 4) {
diff --git a/logcat/logcatd.rc b/logcat/logcatd.rc
index 07040b0..25104eb 100644
--- a/logcat/logcatd.rc
+++ b/logcat/logcatd.rc
@@ -4,10 +4,15 @@
# Make sure any property changes are only performed with /data mounted, after
# post-fs-data state because otherwise behavior is undefined. The exceptions
# are device adjustments for logcatd service properties (persist.* overrides
-# notwithstanding) for logd.logpersistd.size and logd.logpersistd.buffer.
+# notwithstanding) for logd.logpersistd.size logd.logpersistd.rotate_kbytes and
+# logd.logpersistd.buffer.
# persist to non-persistent trampolines to permit device properties can be
# overridden when /data mounts, or during runtime.
+on property:persist.logd.logpersistd.count=*
+ # expect /init to report failure if property empty (default)
+ setprop persist.logd.logpersistd.size ${persist.logd.logpersistd.count}
+
on property:persist.logd.logpersistd.size=256
setprop persist.logd.logpersistd.size ""
setprop logd.logpersistd.size ""
@@ -16,6 +21,14 @@
# expect /init to report failure if property empty (default)
setprop logd.logpersistd.size ${persist.logd.logpersistd.size}
+on property:persist.logd.logpersistd.rotate_kbytes=1024
+ setprop persist.logd.logpersistd.rotate_kbytes ""
+ setprop logd.logpersistd.rotate_kbytes ""
+
+on property:persist.logd.logpersistd.rotate_kbytes=*
+ # expect /init to report failure if property empty (default)
+ setprop logd.logpersistd.rotate_kbytes ${persist.logd.logpersistd.rotate_kbytes}
+
on property:persist.logd.logpersistd.buffer=all
setprop persist.logd.logpersistd.buffer ""
setprop logd.logpersistd.buffer ""
@@ -54,7 +67,7 @@
stop logcatd
# logcatd service
-service logcatd /system/bin/logcatd -L -b ${logd.logpersistd.buffer:-all} -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r 1024 -n ${logd.logpersistd.size:-256} --id=${ro.build.id}
+service logcatd /system/bin/logcatd -L -b ${logd.logpersistd.buffer:-all} -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r ${logd.logpersistd.rotate_kbytes:-1024} -n ${logd.logpersistd.size:-256} --id=${ro.build.id}
class late_start
disabled
# logd for write to /data/misc/logd, log group for read from log daemon
diff --git a/logd/README.property b/logd/README.property
index da5f96f..d2a2cbb 100644
--- a/logd/README.property
+++ b/logd/README.property
@@ -17,10 +17,13 @@
Responds to logcatd, clear and stop.
logd.logpersistd.buffer persist logpersistd buffers to collect
logd.logpersistd.size persist logpersistd size in MB
+logd.logpersistd.rotate_kbytes persist logpersistd outout file size in KB.
persist.logd.logpersistd string Enable logpersist daemon, "logcatd"
turns on logcat -f in logd context.
persist.logd.logpersistd.buffer all logpersistd buffers to collect
persist.logd.logpersistd.size 256 logpersistd size in MB
+persist.logd.logpersistd.count 256 sets max number of rotated logs to <count>.
+persist.logd.logpersistd.rotate_kbytes 1024 logpersistd output file size in KB
persist.logd.size number ro Global default size of the buffer for
all log ids at initial startup, at
runtime use: logcat -b all -G <value>