diff --git a/packages/mediacenter/LibreELEC-settings/package.mk b/packages/mediacenter/LibreELEC-settings/package.mk index 3ea50de679..13d3bd47cc 100644 --- a/packages/mediacenter/LibreELEC-settings/package.mk +++ b/packages/mediacenter/LibreELEC-settings/package.mk @@ -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" diff --git a/packages/mediacenter/kodi/package.mk b/packages/mediacenter/kodi/package.mk index ff26714b0a..bbb6531437 100644 --- a/packages/mediacenter/kodi/package.mk +++ b/packages/mediacenter/kodi/package.mk @@ -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 diff --git a/packages/mediacenter/kodi/scripts/kodi-config b/packages/mediacenter/kodi/scripts/kodi-config index a8586b8d3b..b5a55ac48e 100755 --- a/packages/mediacenter/kodi/scripts/kodi-config +++ b/packages/mediacenter/kodi/scripts/kodi-config @@ -17,28 +17,35 @@ # along with OpenELEC. If not, see . ################################################################################ +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 '' > $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 diff --git a/packages/mediacenter/kodi/scripts/kodi-safe-mode b/packages/mediacenter/kodi/scripts/kodi-safe-mode new file mode 100755 index 0000000000..35506c4e02 --- /dev/null +++ b/packages/mediacenter/kodi/scripts/kodi-safe-mode @@ -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 . +################################################################################ + +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 diff --git a/packages/mediacenter/kodi/scripts/kodi.sh b/packages/mediacenter/kodi/scripts/kodi.sh index 5972aedad8..be89abb0f4 100755 --- a/packages/mediacenter/kodi/scripts/kodi.sh +++ b/packages/mediacenter/kodi/scripts/kodi.sh @@ -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 @@ -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 @@ -74,7 +117,7 @@ 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 @@ -82,7 +125,7 @@ print_crash_report() 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" } @@ -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 @@ -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 diff --git a/packages/mediacenter/kodi/system.d/kodi.service b/packages/mediacenter/kodi/system.d/kodi.service index d6d0250037..e09747bfd1 100644 --- a/packages/mediacenter/kodi/system.d/kodi.service +++ b/packages/mediacenter/kodi/system.d/kodi.service @@ -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 diff --git a/packages/network/samba/scripts/smbd-config b/packages/network/samba/scripts/smbd-config index a3df4ddc85..d381ae8c0b 100755 --- a/packages/network/samba/scripts/smbd-config +++ b/packages/network/samba/scripts/smbd-config @@ -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.