mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-31 06:36:41 +00:00
Merge pull request #2228 from MilhouseVH/le90_safe_mode
kodi: safe mode [RFC]
This commit is contained in:
commit
9155531c28
@ -17,8 +17,8 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
PKG_NAME="LibreELEC-settings"
|
PKG_NAME="LibreELEC-settings"
|
||||||
PKG_VERSION="85b86d4"
|
PKG_VERSION="057ab16"
|
||||||
PKG_SHA256="944f0984f96234e81ae79a595942d830c9554b39c8be8ca287a3c4ff8930c695"
|
PKG_SHA256="dac3e653a5348e3dcd229399343e7a78fa9123e1c721c2a2117d43967f354354"
|
||||||
PKG_ARCH="any"
|
PKG_ARCH="any"
|
||||||
PKG_LICENSE="prop."
|
PKG_LICENSE="prop."
|
||||||
PKG_SITE="https://libreelec.tv"
|
PKG_SITE="https://libreelec.tv"
|
||||||
|
@ -265,8 +265,14 @@ post_makeinstall_target() {
|
|||||||
|
|
||||||
mkdir -p $INSTALL/usr/lib/kodi
|
mkdir -p $INSTALL/usr/lib/kodi
|
||||||
cp $PKG_DIR/scripts/kodi-config $INSTALL/usr/lib/kodi
|
cp $PKG_DIR/scripts/kodi-config $INSTALL/usr/lib/kodi
|
||||||
|
cp $PKG_DIR/scripts/kodi-safe-mode $INSTALL/usr/lib/kodi
|
||||||
cp $PKG_DIR/scripts/kodi.sh $INSTALL/usr/lib/kodi
|
cp $PKG_DIR/scripts/kodi.sh $INSTALL/usr/lib/kodi
|
||||||
|
|
||||||
|
# Configure safe mode triggers - default 5 restarts within 900 seconds/15 minutes
|
||||||
|
$SED -e "s|@KODI_MAX_RESTARTS@|${KODI_MAX_RESTARTS:-5}|g" \
|
||||||
|
-e "s|@KODI_MAX_SECONDS@|${KODI_MAX_SECONDS:-900}|g" \
|
||||||
|
-i $INSTALL/usr/lib/kodi/kodi.sh
|
||||||
|
|
||||||
mkdir -p $INSTALL/usr/sbin
|
mkdir -p $INSTALL/usr/sbin
|
||||||
cp $PKG_DIR/scripts/service-addon-wrapper $INSTALL/usr/sbin
|
cp $PKG_DIR/scripts/service-addon-wrapper $INSTALL/usr/sbin
|
||||||
|
|
||||||
|
@ -17,28 +17,35 @@
|
|||||||
# along with OpenELEC. If not, see <http://www.gnu.org/licenses/>.
|
# along with OpenELEC. If not, see <http://www.gnu.org/licenses/>.
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
|
KODI_ROOT=$HOME/.kodi
|
||||||
|
|
||||||
|
BOOT_STATE="$(cat $HOME/.config/boot.status 2>/dev/null)"
|
||||||
|
|
||||||
# hack: make addon-bins executable
|
# hack: make addon-bins executable
|
||||||
# done in kodi on addon install. but just in case..
|
# done in kodi on addon install. but just in case..
|
||||||
chmod +x /storage/.kodi/addons/*/bin/*
|
chmod +x $KODI_ROOT/addons/*/bin/* 2>/dev/null
|
||||||
|
|
||||||
# hack: update RSSnews.xml in userdata
|
# hack: update RSSnews.xml in userdata
|
||||||
if [ -f /storage/.kodi/userdata/RssFeeds.xml ]; then
|
if [ -f $KODI_ROOT/userdata/RssFeeds.xml ]; then
|
||||||
sed -e "s,http://libreelec.tv/news?format=feed&type=rss,http://feeds.libreelec.tv/news,g" \
|
sed -e "s,http://libreelec.tv/news?format=feed&type=rss,http://feeds.libreelec.tv/news,g" \
|
||||||
-i /storage/.kodi/userdata/RssFeeds.xml
|
-i $KODI_ROOT/userdata/RssFeeds.xml
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# setup Kodi sources
|
# setup Kodi sources
|
||||||
if [ ! -f $HOME/.kodi/userdata/sources.xml ]; then
|
if [ ! -f $KODI_ROOT/userdata/sources.xml ]; then
|
||||||
if [ -f /usr/share/kodi/config/sources.xml ]; then
|
if [ -f /usr/share/kodi/config/sources.xml ]; then
|
||||||
cp /usr/share/kodi/config/sources.xml $HOME/.kodi/userdata
|
cp /usr/share/kodi/config/sources.xml $KODI_ROOT/userdata
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# common setup guisettings
|
# common setup guisettings
|
||||||
if [ ! -f $HOME/.kodi/userdata/guisettings.xml ] ; then
|
if [ ! -f $KODI_ROOT/userdata/guisettings.xml ] ; then
|
||||||
if [ -f /usr/share/kodi/config/guisettings.xml ]; then
|
if [ -f /usr/share/kodi/config/guisettings.xml ]; then
|
||||||
cp /usr/share/kodi/config/guisettings.xml $HOME/.kodi/userdata
|
cp /usr/share/kodi/config/guisettings.xml $KODI_ROOT/userdata
|
||||||
|
fi
|
||||||
|
if [ "$BOOT_STATE" = "SAFE" ]; then
|
||||||
|
[ ! -f $KODI_ROOT/userdata/guisettings.xml ] && echo '<settings version="2"></settings>' > $KODI_ROOT/userdata/guisettings.xml
|
||||||
|
xmlstarlet ed --omit-decl --inplace -s settings -t elem -n setting -v "maroon" -i settings/setting -t attr -n id -v lookandfeel.skincolors $KODI_ROOT/userdata/guisettings.xml
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
49
packages/mediacenter/kodi/scripts/kodi-safe-mode
Executable file
49
packages/mediacenter/kodi/scripts/kodi-safe-mode
Executable file
@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
################################################################################
|
||||||
|
# This file is part of LibreELEC - https://libreelec.tv
|
||||||
|
# Copyright (C) 2016-present Team LibreELEC
|
||||||
|
#
|
||||||
|
# LibreELEC is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# LibreELEC is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with LibreELEC. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
KODI_ROOT=$HOME/.kodi
|
||||||
|
|
||||||
|
KODI_ROOT_FAILED=$KODI_ROOT.FAILED
|
||||||
|
BOOT_STATUS=$HOME/.config/boot.status
|
||||||
|
|
||||||
|
process_boot_status()
|
||||||
|
{
|
||||||
|
BOOT_STATE="$(cat $BOOT_STATUS 2>/dev/null)"
|
||||||
|
|
||||||
|
if [ "${BOOT_STATE}" = "SAFE" ]; then
|
||||||
|
if [ ! -d $KODI_ROOT_FAILED ]; then
|
||||||
|
# entering safe mode - rename failed .kodi, and restart with clean .kodi
|
||||||
|
mv $KODI_ROOT $KODI_ROOT_FAILED
|
||||||
|
reboot
|
||||||
|
else
|
||||||
|
# exiting safe mode - restore failed .kodi
|
||||||
|
rm -fr $KODI_ROOT
|
||||||
|
mv $KODI_ROOT_FAILED $KODI_ROOT
|
||||||
|
echo "OK" > $BOOT_STATUS
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "OK" > $BOOT_STATUS
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
process_boot_status
|
||||||
|
|
||||||
|
exit 0
|
@ -16,8 +16,16 @@
|
|||||||
|
|
||||||
trap cleanup TERM
|
trap cleanup TERM
|
||||||
|
|
||||||
|
KODI_ROOT=$HOME/.kodi
|
||||||
|
|
||||||
SAVED_ARGS="$@"
|
SAVED_ARGS="$@"
|
||||||
CRASHLOG_DIR=/storage/.kodi/temp
|
CRASHLOG_DIR=$KODI_ROOT/temp
|
||||||
|
|
||||||
|
BOOT_STATUS=$HOME/.config/boot.status
|
||||||
|
NOSAFE_MODE=$HOME/.config/safemode.disable
|
||||||
|
CRASH_HIST=/run/libreelec/crashes.dat
|
||||||
|
KODI_MAX_RESTARTS=@KODI_MAX_RESTARTS@
|
||||||
|
KODI_MAX_SECONDS=@KODI_MAX_SECONDS@
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
# make systemd happy by not exiting immediately but
|
# make systemd happy by not exiting immediately but
|
||||||
@ -43,6 +51,41 @@ single_stacktrace()
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
detect_crash_loop()
|
||||||
|
{
|
||||||
|
# use monotonic time (in case date/time changes after booting)
|
||||||
|
NOW_TIME=$(awk '/^now/ {print int($3 / 1000000000)}' /proc/timer_list)
|
||||||
|
echo "$NOW_TIME" >> $CRASH_HIST
|
||||||
|
|
||||||
|
NUM_RESTARTS=$(wc -l $CRASH_HIST | cut -d' ' -f1)
|
||||||
|
FIRST_RESTART_TIME=$(tail -n $MAX_RESTARTS $CRASH_HIST | head -n 1)
|
||||||
|
|
||||||
|
# kodi restart loop detected? fail this kodi install
|
||||||
|
if [ $NUM_RESTARTS -ge $KODI_MAX_RESTARTS -a $KODI_MAX_SECONDS -ge $((NOW_TIME - FIRST_RESTART_TIME)) ]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
activate_safe_mode()
|
||||||
|
{
|
||||||
|
[ -f $NOSAFE_MODE ] && return 0
|
||||||
|
|
||||||
|
BOOT_STATE="$(cat $BOOT_STATUS 2>/dev/null)"
|
||||||
|
|
||||||
|
if [ "${BOOT_STATE:-OK}" = "OK" ]; then
|
||||||
|
# generate logfiles zip for the failed kodi
|
||||||
|
/usr/bin/createlog
|
||||||
|
lastlog=$(ls -1 /storage/logfiles/*.zip | tail -n 1)
|
||||||
|
mv $lastlog /storage/logfiles/log-$(date -u +%Y-%m-%d-%H.%M.%S)-FAILED.zip
|
||||||
|
|
||||||
|
echo "SAFE" > $BOOT_STATUS
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
print_crash_report()
|
print_crash_report()
|
||||||
{
|
{
|
||||||
mkdir -p $CRASHLOG_DIR
|
mkdir -p $CRASHLOG_DIR
|
||||||
@ -74,7 +117,7 @@ print_crash_report()
|
|||||||
echo >> $FILE
|
echo >> $FILE
|
||||||
echo "################# LOG FILE ##################" >> $FILE
|
echo "################# LOG FILE ##################" >> $FILE
|
||||||
echo >> $FILE
|
echo >> $FILE
|
||||||
cat /storage/.kodi/temp/kodi.log >> $FILE
|
cat $KODI_ROOT/temp/kodi.log >> $FILE
|
||||||
echo >> $FILE
|
echo >> $FILE
|
||||||
echo "############### END LOG FILE ################" >> $FILE
|
echo "############### END LOG FILE ################" >> $FILE
|
||||||
echo >> $FILE
|
echo >> $FILE
|
||||||
@ -82,7 +125,7 @@ print_crash_report()
|
|||||||
OFILE="$FILE"
|
OFILE="$FILE"
|
||||||
FILE="$CRASHLOG_DIR/kodi_crashlog_$DATE.log"
|
FILE="$CRASHLOG_DIR/kodi_crashlog_$DATE.log"
|
||||||
mv "$OFILE" "$FILE"
|
mv "$OFILE" "$FILE"
|
||||||
ln -sf "$FILE" "$CRASHLOG_DIR/kodi_crash.log"
|
ln -sf "$(basename $FILE)" "$CRASHLOG_DIR/kodi_crash.log"
|
||||||
echo "Crash report available at $FILE"
|
echo "Crash report available at $FILE"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,8 +137,10 @@ fi
|
|||||||
find /storage/.cache/cores -type f -delete
|
find /storage/.cache/cores -type f -delete
|
||||||
|
|
||||||
# clean zero-byte database files that prevent migration/startup
|
# clean zero-byte database files that prevent migration/startup
|
||||||
for file in /storage/.kodi/userdata/Database/*.db; do
|
for file in $KODI_ROOT/userdata/Database/*.db; do
|
||||||
[ -s $file ] || rm -f $file
|
if [ -e "$file" ]; then
|
||||||
|
[ -s $file ] || rm -f $file
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
/usr/lib/kodi/kodi.bin $SAVED_ARGS
|
/usr/lib/kodi/kodi.bin $SAVED_ARGS
|
||||||
@ -107,6 +152,9 @@ if [ $(( ($RET >= 131 && $RET <= 136) || $RET == 139 )) = "1" ] ; then
|
|||||||
|
|
||||||
# Cleanup. Keep only youngest 10 reports
|
# Cleanup. Keep only youngest 10 reports
|
||||||
rm -f $(ls -1t $CRASHLOG_DIR/kodi_crashlog_*.log | tail -n +11)
|
rm -f $(ls -1t $CRASHLOG_DIR/kodi_crashlog_*.log | tail -n +11)
|
||||||
|
|
||||||
|
# Enable safe mode if a crash loop is detected
|
||||||
|
detect_crash_loop && activate_safe_mode
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit $RET
|
exit $RET
|
||||||
|
@ -16,6 +16,7 @@ EnvironmentFile=-/run/libreelec/debug/kodi.conf
|
|||||||
ExecStartPre=-/usr/lib/kodi/kodi-config
|
ExecStartPre=-/usr/lib/kodi/kodi-config
|
||||||
ExecStart=/usr/lib/kodi/kodi.sh --standalone -fs $KODI_ARGS $KODI_DEBUG
|
ExecStart=/usr/lib/kodi/kodi.sh --standalone -fs $KODI_ARGS $KODI_DEBUG
|
||||||
ExecStop=/bin/kill -TERM $MAINPID
|
ExecStop=/bin/kill -TERM $MAINPID
|
||||||
|
ExecStopPost=-/usr/lib/kodi/kodi-safe-mode
|
||||||
TimeoutStopSec=5
|
TimeoutStopSec=5
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=2
|
RestartSec=2
|
||||||
|
@ -40,6 +40,11 @@ if [ "$SAMBA_AUTOSHARE" == "true" ] ; then
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Allow access to a "failed" (safe mode) Kodi installation
|
||||||
|
if [ -d /storage/.kodi.FAILED ]; then
|
||||||
|
echo -e "[Kodi-Failed]\n path = /storage/.kodi.FAILED\n available = yes\n browsable = yes\n public = yes\n writable = yes\n" >> $SMB_CONF
|
||||||
|
fi
|
||||||
|
|
||||||
ADD_CONFIG=
|
ADD_CONFIG=
|
||||||
|
|
||||||
# If workgroup is not set, don't set it - who knows, user may know better.
|
# If workgroup is not set, don't set it - who knows, user may know better.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user