Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kodi: safe mode [RFC] #2228

Merged
merged 3 commits into from
Dec 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/mediacenter/LibreELEC-settings/package.mk
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
################################################################################

PKG_NAME="LibreELEC-settings"
PKG_VERSION="85b86d4"
PKG_SHA256="944f0984f96234e81ae79a595942d830c9554b39c8be8ca287a3c4ff8930c695"
PKG_VERSION="057ab16"
PKG_SHA256="dac3e653a5348e3dcd229399343e7a78fa9123e1c721c2a2117d43967f354354"
PKG_ARCH="any"
PKG_LICENSE="prop."
PKG_SITE="https://libreelec.tv"
Expand Down
6 changes: 6 additions & 0 deletions packages/mediacenter/kodi/package.mk
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,14 @@ post_makeinstall_target() {

mkdir -p $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

# 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
cp $PKG_DIR/scripts/service-addon-wrapper $INSTALL/usr/sbin

Expand Down
21 changes: 14 additions & 7 deletions packages/mediacenter/kodi/scripts/kodi-config
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,35 @@
# 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
# 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
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" \
-i /storage/.kodi/userdata/RssFeeds.xml
-i $KODI_ROOT/userdata/RssFeeds.xml
fi

# 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
cp /usr/share/kodi/config/sources.xml $HOME/.kodi/userdata
cp /usr/share/kodi/config/sources.xml $KODI_ROOT/userdata
fi
fi

# 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
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

Expand Down
49 changes: 49 additions & 0 deletions packages/mediacenter/kodi/scripts/kodi-safe-mode
Original file line number Diff line number Diff line change
@@ -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
58 changes: 53 additions & 5 deletions packages/mediacenter/kodi/scripts/kodi.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@

trap cleanup TERM

KODI_ROOT=$HOME/.kodi

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() {
# make systemd happy by not exiting immediately but
Expand All @@ -43,6 +51,41 @@ single_stacktrace()
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()
{
mkdir -p $CRASHLOG_DIR
Expand Down Expand Up @@ -74,15 +117,15 @@ print_crash_report()
echo >> $FILE
echo "################# LOG FILE ##################" >> $FILE
echo >> $FILE
cat /storage/.kodi/temp/kodi.log >> $FILE
cat $KODI_ROOT/temp/kodi.log >> $FILE
echo >> $FILE
echo "############### END LOG FILE ################" >> $FILE
echo >> $FILE
echo "############ END kodi CRASH LOG #############" >> $FILE
OFILE="$FILE"
FILE="$CRASHLOG_DIR/kodi_crashlog_$DATE.log"
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"
}

Expand All @@ -94,8 +137,10 @@ fi
find /storage/.cache/cores -type f -delete

# clean zero-byte database files that prevent migration/startup
for file in /storage/.kodi/userdata/Database/*.db; do
[ -s $file ] || rm -f $file
for file in $KODI_ROOT/userdata/Database/*.db; do
if [ -e "$file" ]; then
[ -s $file ] || rm -f $file
fi
done

/usr/lib/kodi/kodi.bin $SAVED_ARGS
Expand All @@ -107,6 +152,9 @@ if [ $(( ($RET >= 131 && $RET <= 136) || $RET == 139 )) = "1" ] ; then

# Cleanup. Keep only youngest 10 reports
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

exit $RET
1 change: 1 addition & 0 deletions packages/mediacenter/kodi/system.d/kodi.service
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ EnvironmentFile=-/run/libreelec/debug/kodi.conf
ExecStartPre=-/usr/lib/kodi/kodi-config
ExecStart=/usr/lib/kodi/kodi.sh --standalone -fs $KODI_ARGS $KODI_DEBUG
ExecStop=/bin/kill -TERM $MAINPID
ExecStopPost=-/usr/lib/kodi/kodi-safe-mode
TimeoutStopSec=5
Restart=always
RestartSec=2
Expand Down
5 changes: 5 additions & 0 deletions packages/network/samba/scripts/smbd-config
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ if [ "$SAMBA_AUTOSHARE" == "true" ] ; then
done
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=

# If workgroup is not set, don't set it - who knows, user may know better.
Expand Down