Imported Upstream version 17.28.8 upstream/17.28.8
authorJinWang An <jinwang.an@samsung.com>
Mon, 27 Dec 2021 00:31:41 +0000 (09:31 +0900)
committerJinWang An <jinwang.an@samsung.com>
Mon, 27 Dec 2021 00:31:41 +0000 (09:31 +0900)
VERSION.cmake
package/libzypp.changes
zypp-core/base/LogControl.cc
zypp-core/base/LogControl.h
zypp-core/zyppng/io/forkspawnengine.cc

index 5989889..f8bc58c 100644 (file)
@@ -61,8 +61,8 @@
 SET(LIBZYPP_MAJOR "17")
 SET(LIBZYPP_COMPATMINOR "22")
 SET(LIBZYPP_MINOR "28")
-SET(LIBZYPP_PATCH "7")
+SET(LIBZYPP_PATCH "8")
 #
-# LAST RELEASED: 17.28.7 (22)
+# LAST RELEASED: 17.28.8 (22)
 # (The number in parenthesis is LIBZYPP_COMPATMINOR)
 #=======
index ada579c..da6121d 100644 (file)
@@ -1,4 +1,10 @@
 -------------------------------------------------------------------
+Thu Nov 11 15:12:44 CET 2021 - ma@suse.de
+
+- Disable logger in the child after fork (bsc#1192436)
+- version 17.28.8 (22)
+
+-------------------------------------------------------------------
 Thu Nov  4 15:16:29 CET 2021 - ma@suse.de
 
 - Check log writer before accessing it (fixes #355, bsc#1192337)
index f2bed4f..faa7170 100644 (file)
@@ -672,6 +672,9 @@ namespace zypp
         {
           logControlValidFlag() = 1;
           std::call_once( flagReadEnvAutomatically, &LogControlImpl::readEnvVars, this);
+
+          // make sure the LogControl is invalidated when we fork
+          pthread_atfork( nullptr, nullptr, &LogControl::notifyFork );
         }
 
       public:
@@ -869,6 +872,11 @@ namespace zypp
       LogThread::instance().stop();
     }
 
+    void LogControl::notifyFork()
+    {
+      logger::logControlValidFlag () = 0;
+    }
+
     ///////////////////////////////////////////////////////////////////
     //
     // LogControl::TmpExcessive
index 730c8d2..de13b7d 100644 (file)
@@ -148,6 +148,13 @@ namespace zypp
       /** will cause the log thread to exit and flush all sockets */
       void emergencyShutdown();
 
+      /**
+       *  This will completely disable logging,
+       *  its supposed to be called in the child process after fork()
+       *  was called to shut down all logging completely
+       */
+      static void notifyFork();
+
     public:
       /** Get the current LineWriter */
       shared_ptr<LineWriter> getLineWriter() const;
index 3bcb1a5..ff3a523 100644 (file)
@@ -9,6 +9,7 @@
 #include <zypp-core/zyppng/base/EventDispatcher>
 #include <zypp-core/zyppng/base/private/linuxhelpers_p.h>
 #include <zypp-core/base/CleanerThread_p.h>
+#include <zypp-core/base/LogControl.h>
 
 #include <cstdint>
 #include <iostream>
@@ -103,7 +104,11 @@ void zyppng::AbstractDirectSpawnEngine::mapExtraFds ( int controlFd )
   const auto maxFds = ( ::getdtablesize() - 1 );
   //If the rlimits are too high we need to use a different approach
   // in detecting how many fds we need to close, or otherwise we are too slow (bsc#1191324)
-  if ( maxFds >= 1024 && zypp::PathInfo( "/proc/self/fd" ).isExist() ) {
+  if ( maxFds > 1024 && zypp::PathInfo( "/proc/self/fd" ).isExist() ) {
+    
+    std::vector<int> fdsToClose;
+    fdsToClose.reserve (256);
+
     zypp::filesystem::dirForEachExt( "/proc/self/fd", [&]( const zypp::Pathname &p, const zypp::filesystem::DirEntry &entry ){
       if ( entry.type != zypp::filesystem::FT_LINK)
         return true;
@@ -112,9 +117,14 @@ void zyppng::AbstractDirectSpawnEngine::mapExtraFds ( int controlFd )
       if ( !fdVal || !canCloseFd(*fdVal) )
         return true;
 
-      ::close( *fdVal );
+      // we can not call close() directly here because zypp::filesystem::dirForEachExt actually has a fd open on
+      // /proc/self/fd that we would close as well. So we just remember which fd's we WOULD close and then do it
+      // after iterating
+      fdsToClose.push_back (*fdVal);
       return true;
     });
+    for ( int cFd : fdsToClose )
+      ::close( cFd );
   } else {
     // close all filedescriptors above the last we want to keep
     for ( int i = maxFds; i > lastFdToKeep; --i ) {
@@ -330,13 +340,13 @@ bool zyppng::ForkSpawnEngine::start( const char * const *argv, int stdin_fd, int
     } else if ( res == zypp::io::ReadAllResult::Ok ) {
       switch( buf.type ) {
         case ChildErrType::CHDIR_FAILED:
-          _execError = zypp::str::form( _("Can't exec '%s', chdir failed (%s)."), _args[0].c_str(), strerror(buf.childErrno) );
+          _execError = zypp::str::form( _("Can't exec '%s', chdir failed (%s)."), _args[0].c_str(), zypp::str::strerror(buf.childErrno).c_str() );
           break;
         case ChildErrType::CHROOT_FAILED:
-          _execError = zypp::str::form( _("Can't exec '%s', chroot failed (%s)."), _args[0].c_str(), strerror(buf.childErrno) );
+          _execError = zypp::str::form( _("Can't exec '%s', chroot failed (%s)."), _args[0].c_str(), zypp::str::strerror(buf.childErrno).c_str() );
           break;
         case ChildErrType::EXEC_FAILED:
-          _execError = zypp::str::form( _("Can't exec '%s', exec failed (%s)."), _args[0].c_str(), strerror(buf.childErrno) );
+          _execError = zypp::str::form( _("Can't exec '%s', exec failed (%s)."), _args[0].c_str(), zypp::str::strerror(buf.childErrno).c_str() );
           break;
         // all other cases need to be some sort of error, because we only get data if the exec fails
         default: