Imported Upstream version 17.0.0
[platform/upstream/libzypp.git] / zypp / media / MediaHandler.cc
index d634c73..2e20218 100644 (file)
 #include <fstream>
 #include <sstream>
 
+#include "zypp/ZConfig.h"
 #include "zypp/TmpPath.h"
 #include "zypp/Date.h"
 #include "zypp/base/LogTools.h"
+#include "zypp/base/Gettext.h"
 #include "zypp/base/String.h"
 #include "zypp/media/MediaHandler.h"
 #include "zypp/media/MediaManager.h"
@@ -56,7 +58,7 @@ MediaHandler::MediaHandler ( const Url &      url_r,
                             const bool       does_download_r )
     : _mediaSource()
     , _attachPoint( new AttachPoint())
-    , _AttachPointHint()
+    , _attachPointHint()
     , _relativeRoot( urlpath_below_attachpoint_r)
     , _does_download( does_download_r )
     , _attach_mtime(0)
@@ -268,8 +270,8 @@ MediaHandler::setAttachPoint(const AttachPointRef &ref)
 void
 MediaHandler::attachPointHint(const Pathname &path, bool temporary)
 {
-  _AttachPointHint.path = path;
-  _AttachPointHint.temp = temporary;
+  _attachPointHint.path = path;
+  _attachPointHint.temp = temporary;
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -283,7 +285,7 @@ MediaHandler::attachPointHint(const Pathname &path, bool temporary)
 AttachPoint
 MediaHandler::attachPointHint() const
 {
-  return _AttachPointHint;
+  return _attachPointHint;
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -340,36 +342,36 @@ MediaHandler::setAttachPrefix(const Pathname &attach_prefix)
 Pathname
 MediaHandler::createAttachPoint() const
 {
-  /////////////////////////////////////////////////////////////////
-  // provide a default (temporary) attachpoint
-  /////////////////////////////////////////////////////////////////
-  const char * defmounts[] = {
-      "/var/adm/mount", filesystem::TmpPath::defaultLocation().c_str(), /**/NULL/**/
-  };
-
+  Pathname aroot;
   Pathname apoint;
-  Pathname aroot( MediaHandler::_attachPrefix);
-
-  if( !aroot.empty())
   {
-    apoint = createAttachPoint(aroot);
+    aroot = MediaHandler::_attachPrefix;       // explicit request
+    if ( ! aroot.empty() )
+      apoint = createAttachPoint( aroot );
   }
-  for ( const char ** def = defmounts; *def && apoint.empty(); ++def ) {
-    aroot = *def;
-    if( aroot.empty())
-      continue;
 
-    apoint = createAttachPoint(aroot);
+  if ( apoint.empty() )                                // fallback to config value
+  {
+    aroot = ZConfig::instance().download_mediaMountdir();
+    if ( ! aroot.empty() )
+      apoint = createAttachPoint( aroot );
   }
 
-  if ( aroot.empty() ) {
-    ERR << "Create attach point: Can't find a writable directory to create an attach point" << std::endl;
-    return aroot;
+  if ( apoint.empty() )                                // fall back to temp space
+  {
+    aroot = filesystem::TmpPath::defaultLocation();
+    if ( ! aroot.empty() )
+      apoint = createAttachPoint( aroot );
   }
 
-  if ( !apoint.empty() ) {
-    MIL << "Created default attach point " << apoint << std::endl;
+  if ( apoint.empty() )
+  {
+    auto except = MediaBadAttachPointException( url() );
+    except.addHistory( _("Create attach point: Can't find a writable directory to create an attach point") );
+    ZYPP_THROW( std::move(except) );
   }
+
+  MIL << "Created default attach point " << apoint << std::endl;
   return apoint;
 }
 
@@ -509,7 +511,7 @@ MediaHandler::checkAttached(bool matchMountFs) const
 {
   bool _isAttached = false;
 
-  AttachedMedia ref( attachedMedia());
+  AttachedMedia ref( attachedMedia() );
   if( ref.mediaSource )
   {
     time_t old_mtime = _attach_mtime;
@@ -529,11 +531,13 @@ MediaHandler::checkAttached(bool matchMountFs) const
       MountEntries entries( MediaManager::getMountEntries());
       for_( e, entries.begin(), entries.end() )
       {
+       if ( ref.attachPoint->path != Pathname(e->dir) )
+         continue;     // at least the mount points must match
+
         bool        is_device = false;
         PathInfo    dev_info;
-
         if( str::hasPrefix( Pathname(e->src).asString(), "/dev/" ) &&
-            dev_info(e->src) && dev_info.isBlk())
+            dev_info(e->src) && dev_info.isBlk() )
         {
           is_device = true;
         }
@@ -542,10 +546,9 @@ MediaHandler::checkAttached(bool matchMountFs) const
                           ref.mediaSource->bdir.empty()))
         {
           std::string mtype(matchMountFs ? e->type : ref.mediaSource->type);
-          MediaSource media(mtype, e->src, dev_info.major(), dev_info.minor());
+          MediaSource media(mtype, e->src, dev_info.devMajor(), dev_info.devMinor());
 
-          if( ref.mediaSource->equals( media) &&
-              ref.attachPoint->path == Pathname(e->dir))
+          if( ref.mediaSource->equals( media ) )
           {
             DBG << "Found media device "
                 << ref.mediaSource->asString()
@@ -569,24 +572,34 @@ MediaHandler::checkAttached(bool matchMountFs) const
                matchMountFs = false;
              else if ( ( e->type == "cifs" || e->type == "smb" ) && ( ref.mediaSource->type == "cifs" || ref.mediaSource->type == "smb" ) )
                matchMountFs = false;
+             else
+               continue;       // different types cannot match
            }
-           std::string mtype(matchMountFs ? e->type : ref.mediaSource->type);
-           MediaSource media(mtype, e->src);
-
-           if( ref.mediaSource->equals( media) &&
-                ref.attachPoint->path == Pathname(e->dir))
+           // Here: Types are ok or not to check.
+           // Check the name except for nfs (bnc#804544; symlink resolution in mount path)
+           //
+           //   [fibonacci]$ ls -l /Local/ma/c12.1
+           //   lrwxrwxrwx  /Local/ma/c12.1 -> zypp-SuSE-Code-12_1-Branch/
+           //
+           //   [localhost]$ mount -t nfs4 fibonacci:/Local/ma/c12.1 /mnt
+           //   [localhost]$ mount
+           //   fibonacci:/Local/ma/zypp-SuSE-Code-12_1-Branch on /mnt
+
+           // std::string mtype(matchMountFs ? e->type : ref.mediaSource->type);
+           // MediaSource media(mtype, e->src);
+
+           if( ref.mediaSource->name == e->src || str::hasPrefix( ref.mediaSource->type, "nfs" ) )
            {
              DBG << "Found media name "
-                  << ref.mediaSource->asString()
-                  << " in the mount table as " << e->src << std::endl;
+             << ref.mediaSource->asString()
+             << " in the mount table as " << e->src << std::endl;
              _isAttached = true;
              break;
            }
          }
          else
          {
-           if(ref.mediaSource->bdir == e->src &&
-              ref.attachPoint->path == Pathname(e->dir))
+           if ( ref.mediaSource->bdir == e->src )
            {
              DBG << "Found bound media "
                  << ref.mediaSource->asString()
@@ -597,6 +610,21 @@ MediaHandler::checkAttached(bool matchMountFs) const
          }
           // differs
         }
+        else // mixed cases:
+       {
+         // Type ISO: Since 11.1 mtab might contain the name of
+         // the loop device instead of the iso file:
+         if ( ref.mediaSource->type == "iso"
+           && str::hasPrefix( Pathname(e->src).asString(), "/dev/loop" )
+           && ref.attachPoint->path == Pathname(e->dir) )
+         {
+           DBG << "Found bound media "
+           << ref.mediaSource->asString()
+           << " in the mount table as " << e->src << std::endl;
+           _isAttached = true;
+           break;
+         }
+       }
       }
 
       if( !_isAttached)
@@ -811,7 +839,7 @@ void MediaHandler::forceRelaseAllMedia(const MediaSourceRef &ref,
     if( is_device &&  ref->maj_nr)
     {
       std::string mtype(matchMountFs ? e->type : ref->type);
-      MediaSource media(mtype, e->src, dev_info.major(), dev_info.minor());
+      MediaSource media(mtype, e->src, dev_info.devMajor(), dev_info.devMinor());
 
       if( ref->equals( media) && e->type != "subfs")
       {