Imported Upstream version 16.6.1
[platform/upstream/libzypp.git] / zypp / media / MediaManager.cc
index 0bf1cf7..b753b51 100644 (file)
@@ -9,24 +9,22 @@
 /** \file zypp/media/MediaManager.cc
  *
 */
-#include <zypp/media/MediaException.h>
-#include <zypp/media/MediaManager.h>
-#include <zypp/media/MediaHandler.h>
-#include <zypp/media/Mount.h>
-#include <zypp/thread/Mutex.h>
-#include <zypp/thread/MutexLock.h>
-#include <zypp/target/hal/HalContext.h>
-
-#include <zypp/base/String.h>
-#include <zypp/base/Logger.h>
-#include <zypp/Pathname.h>
-#include <zypp/PathInfo.h>
-
 #include <map>
 #include <list>
 #include <iostream>
 #include <typeinfo>
 
+#include "zypp/media/MediaException.h"
+#include "zypp/media/MediaManager.h"
+#include "zypp/media/MediaHandler.h"
+#include "zypp/media/Mount.h"
+#include "zypp/thread/Mutex.h"
+#include "zypp/thread/MutexLock.h"
+
+#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
+#include "zypp/Pathname.h"
+#include "zypp/PathInfo.h"
 
 //////////////////////////////////////////////////////////////////////
 namespace zypp
@@ -84,32 +82,21 @@ namespace zypp
           }
         }
 
-        inline void
-        checkDesired(MediaAccessId id)
+        inline void checkDesired( MediaAccessId id )
         {
-          checkAttached(id);
+          checkAttached( id );
 
-          if( !desired)
+          if ( !desired )
           {
-            try {
-              desired = verifier->isDesiredMedia(handler);
-            }
-            catch(const zypp::Exception &e) {
-              ZYPP_CAUGHT(e);
-              desired = false;
-            }
+           desired = verifier->isDesiredMedia(handler);
 
-            if( !desired)
+            if( !desired )
             {
-              DBG << "checkDesired(" << id << "): not desired (report by "
-                  << verifier->info() << ")" << std::endl;
-              ZYPP_THROW(MediaNotDesiredException(
-                handler->url()
-              ));
+              DBG << "checkDesired(" << id << "): not desired (report by " << verifier->info() << ")" << std::endl;
+              ZYPP_THROW( MediaNotDesiredException( handler->url() ) );
             }
 
-            DBG << "checkDesired(" << id << "): desired (report by "
-                << verifier->info() << ")" << std::endl;
+            DBG << "checkDesired(" << id << "): desired (report by " << verifier->info() << ")" << std::endl;
           } else {
             DBG << "checkDesired(" << id << "): desired (cached)" << std::endl;
           }
@@ -124,138 +111,6 @@ namespace zypp
       // -------------------------------------------------------------
       typedef std::map<MediaAccessId, ManagedMedia> ManagedMediaMap;
 
-
-      // -------------------------------------------------------------
-      enum AutoMounterCleanUp
-      {
-        NONE, ENABLE, REMOVE
-      };
-
-      #define HAL_AUTOMOUNTER_UDI  "/org/freedesktop/Hal/devices/computer"
-      #define HAL_AUTOMOUNTER_KEY  "storage.disable_volume_handling"
-
-      // -------------------------------------------------------------
-      AutoMounterCleanUp
-      disableAutoMounter()
-      {
-        using namespace zypp::target::hal;
-
-        AutoMounterCleanUp cleanup(NONE);
-        try
-        {
-          HalContext hal(true);
-          bool disabled(false);
-
-          // query
-          XXX << "Checking HAL volume handling property"
-              << std::endl;
-          try
-          {
-            disabled = hal.getDevicePropertyBool(
-              HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY
-            );
-
-            if( disabled)
-            {
-              MIL << "HAL volume handling is already disabled"
-                  << std::endl;
-            }
-            else
-            {
-              cleanup = ENABLE;
-              XXX << "HAL volume handling is enabled"
-                  << std::endl;
-            }
-          }
-          catch(const HalException &e)
-          {
-            ZYPP_CAUGHT(e);
-            XXX << "HAL volume handling is enabled (no property)"
-                << std::endl;
-            disabled = false;
-            cleanup  = REMOVE;
-          }
-
-          // disable
-          if( !disabled)
-          {
-            XXX << "Trying to disable HAL volume handling"
-                << std::endl;
-            try
-            {
-              hal.setDevicePropertyBool(
-                HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY,
-                true
-              );
-
-              MIL << "Disabled HAL volume handling (automounter)"
-                  << std::endl;
-            }
-            catch(const HalException &e)
-            {
-              ZYPP_CAUGHT(e);
-              WAR << "Unable to disable HAL volume handling (automounter)"
-                  << std::endl;
-
-              cleanup  = NONE;
-            }
-          }
-        }
-        catch(const HalException &e)
-        {
-          ZYPP_CAUGHT(e);
-          WAR << "Unable to disable HAL volume handling (automounter)"
-              << std::endl;
-        }
-        return cleanup;
-      }
-
-      // -------------------------------------------------------------
-      void
-      restoreAutoMounter(AutoMounterCleanUp cleanup)
-      {
-        using namespace zypp::target::hal;
-
-        if(cleanup == NONE)
-          return;
-
-        try
-        {
-          HalContext hal(true);
-
-          if(cleanup == ENABLE)
-          {
-            XXX << "Trying to restore HAL volume handling -- enable"
-                << std::endl;
-
-            hal.setDevicePropertyBool(
-              HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY,
-              false
-            );
-          }
-          else
-          if(cleanup == REMOVE)
-          {
-            XXX << "Trying to restore HAL volume handling -- remove"
-                << std::endl;
-
-            hal.removeDeviceProperty(
-              HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY
-            );
-          }
-
-          cleanup = NONE;
-          MIL << "Restored HAL volume handling (automounter)"
-              << std::endl;
-        }
-        catch(const HalException &e)
-        {
-          ZYPP_CAUGHT(e);
-          WAR << "Unable to restore HAL volume handling (automounter)"
-              << std::endl;
-        }
-      }
-
       ////////////////////////////////////////////////////////////////
     } // anonymous
     //////////////////////////////////////////////////////////////////
@@ -284,15 +139,11 @@ namespace zypp
       friend class MediaManager;
 
       MediaAccessId       last_accessid;
-      AutoMounterCleanUp  am_cleanup;
       ManagedMediaMap     mediaMap;
 
       MediaManager_Impl()
         : last_accessid(0)
-      {
-        // disable automounter
-        am_cleanup = disableAutoMounter();
-      }
+      {}
 
     public:
       ~MediaManager_Impl()
@@ -324,9 +175,6 @@ namespace zypp
 
           // remove all other handlers
           mediaMap.clear();
-
-          // restore automounter state
-          restoreAutoMounter(am_cleanup);
         }
         catch( ... )
         {}
@@ -372,9 +220,7 @@ namespace zypp
       static inline MountEntries
       getMountEntries()
       {
-        // use "/etc/mtab" by default,
-        // fallback to "/proc/mounts"
-        return Mount::getEntries(/* "/etc/mtab" */);
+        return Mount::getEntries();
       }
 
     };
@@ -382,7 +228,7 @@ namespace zypp
 
     //////////////////////////////////////////////////////////////////
     // STATIC
-    zypp::RW_pointer<MediaManager_Impl> MediaManager::m_impl(NULL);
+    zypp::RW_pointer<MediaManager_Impl> MediaManager::m_impl;
 
 
     //////////////////////////////////////////////////////////////////
@@ -492,14 +338,6 @@ namespace zypp
     }
 
     // ---------------------------------------------------------------
-    // STATIC
-    bool
-    MediaManager::downloads(const Url &url)
-    {
-      return MediaAccess::downloads( url);
-    }
-
-    // ---------------------------------------------------------------
     Url
     MediaManager::url(MediaAccessId accessId) const
     {
@@ -555,28 +393,88 @@ namespace zypp
     }
 
     // ---------------------------------------------------------------
-    void
-    MediaManager::attach(MediaAccessId accessId, bool next)
+    void MediaManager::attach(MediaAccessId accessId)
     {
       MutexLock glock(g_Mutex);
 
       ManagedMedia &ref( m_impl->findMM(accessId));
 
       DBG << "attach(id=" << accessId << ")" << std::endl;
-      return ref.handler->attach(next);
+
+      // try first mountable/mounted device
+      ref.handler->attach(false);
+      try
+      {
+        ref.checkDesired(accessId);
+        return;
+      }
+      catch (const MediaException & ex)
+      {
+        ZYPP_CAUGHT(ex);
+
+        if (!ref.handler->hasMoreDevices())
+          ZYPP_RETHROW(ex);
+
+        if (ref.handler->isAttached())
+          ref.handler->release();
+      }
+
+      MIL << "checkDesired(" << accessId << ") of first device failed,"
+        " going to try others with attach(true)" << std::endl;
+
+      while (ref.handler->hasMoreDevices())
+      {
+        try
+        {
+          // try to attach next device
+          ref.handler->attach(true);
+          ref.checkDesired(accessId);
+          return;
+        }
+        catch (const MediaNotDesiredException & ex)
+        {
+          ZYPP_CAUGHT(ex);
+
+          if (!ref.handler->hasMoreDevices())
+          {
+            MIL << "No desired media found after trying all detected devices." << std::endl;
+            ZYPP_RETHROW(ex);
+          }
+
+          AttachedMedia media(ref.handler->attachedMedia());
+          DBG << "Skipping " << media.mediaSource->asString() << ": not desired media." << std::endl;
+
+          ref.handler->release();
+        }
+        catch (const MediaException & ex)
+        {
+          ZYPP_CAUGHT(ex);
+
+          if (!ref.handler->hasMoreDevices())
+            ZYPP_RETHROW(ex);
+
+          AttachedMedia media(ref.handler->attachedMedia());
+          DBG << "Skipping " << media.mediaSource->asString() << " because of exception thrown by attach(true)" << std::endl;
+
+          if (ref.handler->isAttached()) ref.handler->release();
+        }
+      }
     }
 
     // ---------------------------------------------------------------
     void
-    MediaManager::release(MediaAccessId accessId, bool eject)
+    MediaManager::release(MediaAccessId accessId, const std::string & ejectDev)
     {
       MutexLock glock(g_Mutex);
 
       ManagedMedia &ref( m_impl->findMM(accessId));
 
-      DBG << "release(id=" << accessId
-          << (eject ? ", eject)" : ")") << std::endl;
-      if( eject)
+      DBG << "release(id=" << accessId;
+      if (!ejectDev.empty())
+        DBG << ", " << ejectDev;
+      DBG << ")" << std::endl;
+
+      if(!ejectDev.empty())
       {
         //
         // release MediaISO handlers, that are using the one
@@ -594,7 +492,7 @@ namespace zypp
               DBG << "Forcing release of handler depending on access id "
                   << accessId << std::endl;
               m->second.desired  = false;
-              m->second.handler->release(!eject);
+              m->second.handler->release();
             }
             catch(const MediaException &e)
             {
@@ -604,7 +502,44 @@ namespace zypp
         }
       }
       ref.desired  = false;
-      ref.handler->release(eject);
+      ref.handler->release(ejectDev);
+    }
+
+    // ---------------------------------------------------------------
+    void
+    MediaManager::releaseAll()
+    {
+      MutexLock glock(g_Mutex);
+
+      MIL << "Releasing all attached media" << std::endl;
+
+      ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
+      for( ; m != m_impl->mediaMap.end(); ++m)
+      {
+        if( m->second.handler->dependsOnParent())
+          continue;
+
+        try
+        {
+          if(m->second.handler->isAttached())
+          {
+            DBG << "Releasing media id " << m->first << std::endl;
+            m->second.desired  = false;
+            m->second.handler->release();
+          }
+          else
+          {
+            DBG << "Media id " << m->first << " not attached " << std::endl;
+          }
+        }
+        catch(const MediaException & e)
+        {
+          ZYPP_CAUGHT(e);
+          ERR << "Failed to release media id " << m->first << std::endl;
+        }
+      }
+
+      MIL << "Exit" << std::endl;
     }
 
     // ---------------------------------------------------------------
@@ -700,6 +635,13 @@ namespace zypp
     }
 
     // ---------------------------------------------------------------
+    bool
+    MediaManager::isChangeable(MediaAccessId accessId)
+    {
+      return url(accessId).getScheme() == "cd" || url(accessId).getScheme() == "dvd";
+    }
+
+    // ---------------------------------------------------------------
     Pathname
     MediaManager::localRoot(MediaAccessId accessId) const
     {
@@ -729,9 +671,21 @@ namespace zypp
     // ---------------------------------------------------------------
     void
     MediaManager::provideFile(MediaAccessId   accessId,
-                              const Pathname &filename,
-                              bool            cached,
-                              bool            checkonly) const
+                              const Pathname &filename ) const
+    {
+      MutexLock glock(g_Mutex);
+
+      ManagedMedia &ref( m_impl->findMM(accessId));
+
+      ref.checkDesired(accessId);
+
+      ref.handler->provideFile(filename);
+    }
+
+    // ---------------------------------------------------------------
+    void
+    MediaManager::setDeltafile(MediaAccessId   accessId,
+                              const Pathname &filename ) const
     {
       MutexLock glock(g_Mutex);
 
@@ -739,7 +693,7 @@ namespace zypp
 
       ref.checkDesired(accessId);
 
-      ref.handler->provideFile(filename, cached, checkonly);
+      ref.handler->setDeltafile(filename);
     }
 
     // ---------------------------------------------------------------
@@ -848,6 +802,30 @@ namespace zypp
     }
 
     // ---------------------------------------------------------------
+    bool
+    MediaManager::doesFileExist(MediaAccessId  accessId, const Pathname & filename ) const
+    {
+      MutexLock glock(g_Mutex);
+      ManagedMedia &ref( m_impl->findMM(accessId));
+
+      // FIXME: ref.checkDesired(accessId); ???
+      ref.checkAttached(accessId);
+
+      return ref.handler->doesFileExist(filename);
+    }
+
+    // ---------------------------------------------------------------
+    void
+    MediaManager::getDetectedDevices(MediaAccessId accessId,
+                                     std::vector<std::string> & devices,
+                                     unsigned int & index) const
+    {
+      MutexLock glock(g_Mutex);
+      ManagedMedia &ref( m_impl->findMM(accessId));
+      return ref.handler->getDetectedDevices(devices, index);
+    }
+
+    // ---------------------------------------------------------------
     // STATIC
     time_t
     MediaManager::getMountTableMTime()
@@ -988,7 +966,7 @@ namespace zypp
         AttachedMedia ret = m->second.handler->attachedMedia();
         if( ret.mediaSource && ret.mediaSource->equals( *media))
         {
-          m->second.handler->release(false);
+          m->second.handler->release();
           m->second.desired  = false;
         }
       }