[Libreoffice-commits] online.git: loolwsd.xml.in wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/LOOLWSD.cpp

Michael Meeks (via logerrit) logerrit at kemper.freedesktop.org
Thu Dec 12 03:40:06 UTC 2019


 loolwsd.xml.in         |    1 +
 wsd/DocumentBroker.cpp |   22 ++++++++++++++++++++++
 wsd/DocumentBroker.hpp |    2 ++
 wsd/LOOLWSD.cpp        |    1 +
 4 files changed, 26 insertions(+)

New commits:
commit 83e02ab38b4ffee6c350d1ba01bc8c7e89c02b77
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Thu Dec 12 03:38:50 2019 +0000
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Thu Dec 12 03:38:50 2019 +0000

    Add a time limit for badly behaved / huge document conversions.
    
    Handles problems with load, save, and lingering DocumentBrokers.
    
    Change-Id: I6079cba3a4fa2a84c303b3a8669d94863a04f474

diff --git a/loolwsd.xml.in b/loolwsd.xml.in
index 6b81a4385..71f6b8f6f 100644
--- a/loolwsd.xml.in
+++ b/loolwsd.xml.in
@@ -29,6 +29,7 @@
         <limit_file_size_mb desc="The maximum file size allowed to each document process to write. 0 for unlimited." type="uint">0</limit_file_size_mb>
         <limit_num_open_files desc="The maximum number of files allowed to each document process to open. 0 for unlimited." type="uint">0</limit_num_open_files>
         <limit_load_secs desc="Maximum number of seconds to wait for a document load to succeed. 0 for unlimited." type="uint" default="100">100</limit_load_secs>
+        <limit_convert_secs desc="Maximum number of seconds to wait for a document conversion to succeed. 0 for unlimited." type="uint" default="100">100</limit_convert_secs>
     </per_document>
 
     <per_view desc="View-specific settings.">
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 1fb51b513..af756c676 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -175,6 +175,7 @@ std::atomic<unsigned> DocumentBroker::DocBrokerId(1);
 DocumentBroker::DocumentBroker(const std::string& uri,
                                const Poco::URI& uriPublic,
                                const std::string& docKey) :
+    _limitLifeSeconds(0),
     _uriOrig(uri),
     _uriPublic(uriPublic),
     _docKey(docKey),
@@ -314,6 +315,22 @@ void DocumentBroker::pollThread()
             continue;
         }
 
+        if (_limitLifeSeconds > 0 &&
+            std::chrono::duration_cast<std::chrono::seconds>(now - _threadStart).count() > _limitLifeSeconds)
+        {
+            LOG_WRN("Doc [" << _docKey << "] is taking too long to convert. Will kill process ["
+                            << _childProcess->getPid() << "]. per_document.limit_convert_secs set to "
+                            << _limitLifeSeconds << " secs.");
+            broadcastMessage("error: cmd=load kind=docexpired");
+
+            // Brutal but effective.
+            if (_childProcess)
+                _childProcess->terminate();
+
+            stop("Load timed out");
+            continue;
+        }
+
         if (std::chrono::duration_cast<std::chrono::milliseconds>
                     (now - lastBWUpdateTime).count() >= COMMAND_TIMEOUT_MS)
         {
@@ -2181,7 +2198,9 @@ ConvertToBroker::ConvertToBroker(const std::string& uri,
                                  const std::string& docKey)
     : DocumentBroker(uri, uriPublic, docKey)
 {
+    static const int limit_convert_secs = LOOLWSD::getConfigValue<int>("per_document.limit_convert_secs", 100);
     NumConverters++;
+    _limitLifeSeconds = limit_convert_secs;
 }
 
 void ConvertToBroker::dispose()
@@ -2252,11 +2271,14 @@ void DocumentBroker::dumpState(std::ostream& os)
     os << "\n  doc key: " << _docKey;
     os << "\n  doc id: " << _docId;
     os << "\n  num sessions: " << _sessions.size();
+    os << "\n  thread start: " << Util::getSteadyClockAsString(_threadStart);
     os << "\n  last saved: " << Util::getSteadyClockAsString(_lastSaveTime);
     os << "\n  last save request: " << Util::getSteadyClockAsString(_lastSaveRequestTime);
     os << "\n  last save response: " << Util::getSteadyClockAsString(_lastSaveResponseTime);
     os << "\n  last modifed: " << Util::getHttpTime(_documentLastModifiedTime);
     os << "\n  file last modifed: " << Util::getHttpTime(_lastFileModifiedTime);
+    if (_limitLifeSeconds)
+        os << "\n  life limit in seconds: " << _limitLifeSeconds;
     os << "\n  idle time: " << getIdleTimeSecs();
     os << "\n  cursor " << _cursorPosX << ", " << _cursorPosY
       << "( " << _cursorWidth << "," << _cursorHeight << ")\n";
diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp
index 19c88e4c4..3b8f6e844 100644
--- a/wsd/DocumentBroker.hpp
+++ b/wsd/DocumentBroker.hpp
@@ -443,6 +443,8 @@ private:
     void getIOStats(uint64_t &sent, uint64_t &recv);
 
 protected:
+    /// Seconds to live for, or 0 forever
+    int64_t _limitLifeSeconds;
     std::string _uriOrig;
 private:
     const Poco::URI _uriPublic;
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index faa399756..524415b6f 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -835,6 +835,7 @@ void LOOLWSD::initialize(Application& self)
             { "per_document.limit_file_size_mb", "0" },
             { "per_document.limit_num_open_files", "0" },
             { "per_document.limit_load_secs", "100" },
+            { "per_document.limit_convert_secs", "100" },
             { "per_document.limit_stack_mem_kb", "8000" },
             { "per_document.limit_virt_mem_mb", "0" },
             { "per_document.max_concurrency", "4" },


More information about the Libreoffice-commits mailing list