From b4322e10bb080404c5c622b856ed3a29617c703b Mon Sep 17 00:00:00 2001 From: smlee Date: Mon, 21 Nov 2016 18:21:53 +0900 Subject: [PATCH] Limit filesize for Timeshift on eMMC (<2GBytes) --- lib/base/filepush.cpp | 73 +++++++++++++++++++++++++++++++++++ lib/base/filepush.h | 1 + lib/dvb/dvb.cpp | 4 ++ lib/dvb/pmt.cpp | 3 ++ lib/dvb/pmt.h | 1 + lib/python/Screens/InfoBarGenerics.py | 6 ++- lib/service/servicedvb.cpp | 4 ++ 7 files changed, 91 insertions(+), 1 deletion(-) diff --git a/lib/base/filepush.cpp b/lib/base/filepush.cpp index eb80914..5de9ef2 100644 --- a/lib/base/filepush.cpp +++ b/lib/base/filepush.cpp @@ -1,12 +1,24 @@ #include #include +#include #include #include #include +#include +#if 0 +#include +#else +#include +#endif #define PVR_COMMIT 1 +#define MAJORSD_ 8 +#define MAJORMMCBLK 179 +#define LIMIT_FILESIZE_NOHDD 2*1024*1024*1024LL // 2GBytes + //FILE *f = fopen("/log.ts", "wb"); +static bool g_is_diskfull = false; eFilePushThread::eFilePushThread(int io_prio_class, int io_prio_level, int blocksize) :prio_class(io_prio_class), prio(io_prio_level), m_messagepump(eApp, 0) @@ -19,6 +31,7 @@ eFilePushThread::eFilePushThread(int io_prio_class, int io_prio_level, int block flush(); enablePVRCommit(0); CONNECT(m_messagepump.recv_msg, eFilePushThread::recvEvent); + m_hdd_connected = false; } static void signal_handler(int x) @@ -37,6 +50,39 @@ void eFilePushThread::thread() size_t written_since_last_sync = 0; + std::string tspath; + if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1) { + eDebug("could not query ts path from config"); + } + tspath.append("/"); + +#if 0 + DIR *tsdir_info; + struct dirent *tsdir_entry; + tsdir_info = opendir("/sys/block"); + if (tsdir_info != NULL) { + m_hdd_connected = false; + while (tsdir_entry = readdir(tsdir_info)) { + if (strncmp(tsdir_entry->d_name, "sd", 2) == 0) { + eDebug("HDD found: %s", tsdir_entry->d_name); + m_hdd_connected = true; + break; + } + } + } +#else + struct stat tspath_st; + if (stat(tspath.c_str(), &tspath_st) == 0) { + if (major(tspath_st.st_dev) == MAJORSD_) { + eDebug("Timeshift location on HDD!"); + m_hdd_connected = true; + } else if (major(tspath_st.st_dev) == MAJORMMCBLK) { + eDebug("Timeshift location on eMMC!"); + m_hdd_connected = false; + } + } +#endif + eDebug("FILEPUSH THREAD START"); /* we set the signal to not restart syscalls, so we can detect our signal. */ @@ -110,6 +156,15 @@ void eFilePushThread::thread() continue; eDebug("eFilePushThread WRITE ERROR"); sendEvent(evtWriteError); + + struct statfs fs; + if (statfs(tspath.c_str(), &fs) < 0) { + eDebug("statfs failed!"); + } + if ((off_t)fs.f_bavail < 1) { + eDebug("not enough diskspace for timeshift!"); + g_is_diskfull = true; + } break; // ... we would stop the thread } @@ -131,6 +186,19 @@ void eFilePushThread::thread() continue; } + if (!m_hdd_connected) { + struct stat limit_filesize; + if (fstat(m_fd_dest, &limit_filesize) == 0) { + if (limit_filesize.st_size > LIMIT_FILESIZE_NOHDD) { + eDebug("eFilePushThread %lld > %lld LIMIT FILESIZE", limit_filesize.st_size, LIMIT_FILESIZE_NOHDD); + sendEvent(evtWriteError); + + g_is_diskfull = true; + break; + } + } + } + /* now fill our buffer. */ if (m_sg && !current_span_remaining) @@ -218,6 +286,11 @@ void eFilePushThread::thread() current_span_remaining -= m_buf_end; } // printf("FILEPUSH: read %d bytes\n", m_buf_end); + + if (g_is_diskfull) { + sendEvent(evtUser+3); + g_is_diskfull = false; + } } fdatasync(m_fd_dest); diff --git a/lib/base/filepush.h b/lib/base/filepush.h index a4457f6..3fb051e 100644 --- a/lib/base/filepush.h +++ b/lib/base/filepush.h @@ -63,6 +63,7 @@ private: ePtr m_source; eFixedMessagePump m_messagepump; + bool m_hdd_connected; void recvEvent(const int &evt); }; diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 0c36b7c..012a834 100755 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -1426,6 +1426,10 @@ void eDVBChannel::pvrEvent(int event) eDebug("SOF"); m_event(this, evtSOF); break; + case eFilePushThread::evtUser+3: /* limit space */ + eDebug("Too large file"); + m_event(this, evtFailed+3); + break; } } diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 5132b38..e6c1d2c 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -106,6 +106,9 @@ void eDVBServicePMTHandler::channelEvent(iDVBChannel *channel, int event) case iDVBChannel::evtSOF: serviceEvent(eventSOF); break; + case iDVBChannel::evtFailed+3: + serviceEvent(eventNoDiskSpace); + break; default: break; } diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h index b2fc68f..eb4f593 100644 --- a/lib/dvb/pmt.h +++ b/lib/dvb/pmt.h @@ -189,6 +189,7 @@ public: eventHBBTVInfo, /* HBBTV information was detected in the AIT */ eventMisconfiguration, // a channel was not found in any list, or no frontend was found which could provide this channel + eventNoDiskSpace, // no disk space available }; #ifndef SWIG Signal1 serviceEvent; diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index 5a556c0..a6d25d5 100755 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -1204,7 +1204,8 @@ class InfoBarTimeshift: self.__event_tracker = ServiceEventTracker(screen=self, eventmap= { iPlayableService.evStart: self.__serviceStarted, - iPlayableService.evSeekableStatusChanged: self.__seekableStatusChanged + iPlayableService.evSeekableStatusChanged: self.__seekableStatusChanged, + iPlayableService.evUser+3: self.__lowDiskspaceMessage }) def getTimeshift(self): @@ -1308,6 +1309,9 @@ class InfoBarTimeshift: self.timeshift_enabled = False self.__seekableStatusChanged() + def __lowDiskspaceMessage(self): + Notifications.AddPopup(text = _("Write error. Not enough space for writing.\n"), type = MessageBox.TYPE_ERROR, timeout = 0, id = "DiskFullMessage") + from Screens.PiPSetup import PiPSetup class InfoBarExtensions: diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index c3abb81..2bd6998 100755 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -1169,6 +1169,10 @@ void eDVBServicePlay::serviceEventTimeshift(int event) } } break; + case eDVBServicePMTHandler::eventNoDiskSpace: + eDebug("No space!"); + m_event((iPlayableService*)this, evUser+3); + break; } } -- 2.7.4