MediaManager.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <zypp/media/MediaException.h>
00013 #include <zypp/media/MediaManager.h>
00014 #include <zypp/media/MediaHandler.h>
00015 #include <zypp/media/Mount.h>
00016 #include <zypp/thread/Mutex.h>
00017 #include <zypp/thread/MutexLock.h>
00018 #include <zypp/target/hal/HalContext.h>
00019 
00020 #include <zypp/base/String.h>
00021 #include <zypp/base/Logger.h>
00022 #include <zypp/Pathname.h>
00023 #include <zypp/PathInfo.h>
00024 
00025 #include <map>
00026 #include <list>
00027 #include <iostream>
00028 #include <typeinfo>
00029 
00030 #define  DISABLE_AUTOMOUNTER      0
00031 
00032 
00034 namespace zypp
00035 { 
00036 
00038   namespace media
00039   { 
00040 
00041     using zypp::thread::Mutex;
00042     using zypp::thread::MutexLock;
00043 
00045     namespace // anonymous
00046     { 
00047 
00048 
00049       // -------------------------------------------------------------
00050       // STATIC
00051       static Mutex  g_Mutex;
00052 
00053 
00054       // -------------------------------------------------------------
00055       struct ManagedMedia
00056       {
00057         ~ManagedMedia()
00058         {}
00059 
00060         ManagedMedia()
00061           : desired (false)
00062         {}
00063 
00064         ManagedMedia(const ManagedMedia &m)
00065           : desired (m.desired)
00066           , handler (m.handler)
00067           , verifier(m.verifier)
00068         {}
00069 
00070         ManagedMedia(const MediaAccessRef &h, const MediaVerifierRef &v)
00071           : desired (false)
00072           , handler (h)
00073           , verifier(v)
00074         {}
00075 
00076         inline void
00077         checkAttached(MediaAccessId id)
00078         {
00079           if( !handler->isAttached())
00080           {
00081             DBG << "checkAttached(" << id << ") not attached" << std::endl;
00082             desired = false;
00083             ZYPP_THROW(MediaNotAttachedException(
00084               handler->url()
00085             ));
00086           }
00087         }
00088 
00089         inline void
00090         checkDesired(MediaAccessId id)
00091         {
00092           checkAttached(id);
00093 
00094           if( !desired)
00095           {
00096             try {
00097               desired = verifier->isDesiredMedia(handler);
00098             }
00099             catch(const zypp::Exception &e) {
00100               ZYPP_CAUGHT(e);
00101               desired = false;
00102             }
00103 
00104             if( !desired)
00105             {
00106               DBG << "checkDesired(" << id << "): not desired (report by "
00107                   << verifier->info() << ")" << std::endl;
00108               ZYPP_THROW(MediaNotDesiredException(
00109                 handler->url()
00110               ));
00111             }
00112 
00113             DBG << "checkDesired(" << id << "): desired (report by "
00114                 << verifier->info() << ")" << std::endl;
00115           } else {
00116             DBG << "checkDesired(" << id << "): desired (cached)" << std::endl;
00117           }
00118         }
00119 
00120         bool             desired;
00121         MediaAccessRef   handler;
00122         MediaVerifierRef verifier;
00123       };
00124 
00125 
00126       // -------------------------------------------------------------
00127       typedef std::map<MediaAccessId, ManagedMedia> ManagedMediaMap;
00128 
00129 
00130       // -------------------------------------------------------------
00131       enum AutoMounterCleanUp
00132       {
00133         NONE, ENABLE, REMOVE
00134       };
00135 
00136       #define HAL_AUTOMOUNTER_UDI  "/org/freedesktop/Hal/devices/computer"
00137       #define HAL_AUTOMOUNTER_KEY  "storage.disable_volume_handling"
00138 
00139       // -------------------------------------------------------------
00140       AutoMounterCleanUp
00141       disableAutoMounter()
00142       {
00143         using namespace zypp::target::hal;
00144 
00145         AutoMounterCleanUp cleanup(NONE);
00146 #if DISABLE_AUTOMOUNTER
00147         try
00148         {
00149           HalContext hal(true);
00150           bool disabled(false);
00151 
00152           // query
00153           XXX << "Checking HAL volume handling property"
00154               << std::endl;
00155           try
00156           {
00157             disabled = hal.getDevicePropertyBool(
00158               HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY
00159             );
00160 
00161             if( disabled)
00162             {
00163               MIL << "HAL volume handling is already disabled"
00164                   << std::endl;
00165             }
00166             else
00167             {
00168               cleanup = ENABLE;
00169               XXX << "HAL volume handling is enabled"
00170                   << std::endl;
00171             }
00172           }
00173           catch(const HalException &e)
00174           {
00175             ZYPP_CAUGHT(e);
00176             XXX << "HAL volume handling is enabled (no property)"
00177                 << std::endl;
00178             disabled = false;
00179             cleanup  = REMOVE;
00180           }
00181 
00182           // disable
00183           if( !disabled)
00184           {
00185             XXX << "Trying to disable HAL volume handling"
00186                 << std::endl;
00187             try
00188             {
00189               hal.setDevicePropertyBool(
00190                 HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY,
00191                 true
00192               );
00193 
00194               MIL << "Disabled HAL volume handling (automounter)"
00195                   << std::endl;
00196             }
00197             catch(const HalException &e)
00198             {
00199               ZYPP_CAUGHT(e);
00200               WAR << "Unable to disable HAL volume handling (automounter)"
00201                   << std::endl;
00202 
00203               cleanup  = NONE;
00204             }
00205           }
00206         }
00207         catch(const HalException &e)
00208         {
00209           ZYPP_CAUGHT(e);
00210           WAR << "Unable to disable HAL volume handling (automounter)"
00211               << std::endl;
00212         }
00213 #endif // DISABLE_AUTOMOUNTER
00214         return cleanup;
00215       }
00216 
00217       // -------------------------------------------------------------
00218       void
00219       restoreAutoMounter(AutoMounterCleanUp cleanup)
00220       {
00221         using namespace zypp::target::hal;
00222 
00223         if(cleanup == NONE)
00224           return;
00225 
00226 #if DISABLE_AUTOMOUNTER
00227         try
00228         {
00229           HalContext hal(true);
00230 
00231           if(cleanup == ENABLE)
00232           {
00233             XXX << "Trying to restore HAL volume handling -- enable"
00234                 << std::endl;
00235 
00236             hal.setDevicePropertyBool(
00237               HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY,
00238               false
00239             );
00240           }
00241           else
00242           if(cleanup == REMOVE)
00243           {
00244             XXX << "Trying to restore HAL volume handling -- remove"
00245                 << std::endl;
00246 
00247             hal.removeDeviceProperty(
00248               HAL_AUTOMOUNTER_UDI, HAL_AUTOMOUNTER_KEY
00249             );
00250           }
00251 
00252           cleanup = NONE;
00253           MIL << "Restored HAL volume handling (automounter)"
00254               << std::endl;
00255         }
00256         catch(const HalException &e)
00257         {
00258           ZYPP_CAUGHT(e);
00259           WAR << "Unable to restore HAL volume handling (automounter)"
00260               << std::endl;
00261         }
00262 #endif // DISABLE_AUTOMOUNTER
00263       }
00264 
00266     } // anonymous
00268 
00269 
00271     std::string
00272     MediaVerifierBase::info() const
00273     {
00274       return std::string(typeid((*this)).name());
00275     }
00276 
00277 
00279     std::string
00280     NoVerifier::info() const
00281     {
00282       return std::string("zypp::media::NoVerifier");
00283     }
00284 
00285 
00287     class MediaManager_Impl
00288     {
00289     private:
00290       friend class MediaManager;
00291 
00292       MediaAccessId       last_accessid;
00293       AutoMounterCleanUp  am_cleanup;
00294       ManagedMediaMap     mediaMap;
00295 
00296       MediaManager_Impl()
00297         : last_accessid(0)
00298       {
00299         // disable automounter
00300         am_cleanup = disableAutoMounter();
00301       }
00302 
00303     public:
00304       ~MediaManager_Impl()
00305       {
00306         MutexLock glock(g_Mutex);
00307 
00308         try
00309         {
00310           // remove depending (iso) handlers first
00311           ManagedMediaMap::iterator it;
00312           bool found;
00313           do
00314           {
00315             found = false;
00316             for(it = mediaMap.begin(); it != mediaMap.end(); )
00317             {
00318               if( it->second.handler->dependsOnParent())
00319               {
00320                 found = true;
00321                 // let it forget its parent, we will
00322                 // destroy it later (in clear())...
00323                 it->second.handler->resetParentId();
00324                 mediaMap.erase( it++ ); // postfix! Incrementing before erase
00325               } else {
00326                 ++it;
00327               }
00328             }
00329           } while(found);
00330 
00331           // remove all other handlers
00332           mediaMap.clear();
00333 
00334           // restore automounter state
00335           restoreAutoMounter(am_cleanup);
00336         }
00337         catch( ... )
00338         {}
00339       }
00340 
00341       inline MediaAccessId
00342       nextAccessId()
00343       {
00344         return ++last_accessid;
00345       }
00346 
00347       inline bool
00348       hasId(MediaAccessId accessId) const
00349       {
00350         return mediaMap.find(accessId) != mediaMap.end();
00351       }
00352 
00353       inline ManagedMedia &
00354       findMM(MediaAccessId accessId)
00355       {
00356         ManagedMediaMap::iterator it( mediaMap.find(accessId));
00357         if( it == mediaMap.end())
00358         {
00359           ZYPP_THROW(MediaNotOpenException(
00360             "Invalid media access id " + str::numstring(accessId)
00361           ));
00362         }
00363         return it->second;
00364       }
00365 
00366       static inline time_t
00367       getMountTableMTime()
00368       {
00369         time_t mtime = zypp::PathInfo("/etc/mtab").mtime();
00370         if( mtime <= 0)
00371         {
00372           WAR << "Failed to retrieve modification time of '/etc/mtab'"
00373               << std::endl;
00374         }
00375         return mtime;
00376       }
00377 
00378       static inline MountEntries
00379       getMountEntries()
00380       {
00381         // use "/etc/mtab" by default,
00382         // fallback to "/proc/mounts"
00383         return Mount::getEntries(/* "/etc/mtab" */);
00384       }
00385 
00386     };
00387 
00388 
00390     // STATIC
00391     zypp::RW_pointer<MediaManager_Impl> MediaManager::m_impl(NULL);
00392 
00393 
00395     MediaManager::MediaManager()
00396     {
00397       MutexLock glock(g_Mutex);
00398       if( !m_impl)
00399       {
00400         m_impl.reset( new MediaManager_Impl());
00401       }
00402     }
00403 
00404     // ---------------------------------------------------------------
00405     MediaManager::~MediaManager()
00406     {
00407     }
00408 
00409     // ---------------------------------------------------------------
00410     MediaAccessId
00411     MediaManager::open(const Url &url, const Pathname &preferred_attach_point)
00412     {
00413       MutexLock glock(g_Mutex);
00414 
00415       // create new access handler for it
00416       MediaAccessRef handler( new MediaAccess());
00417       MediaVerifierRef verifier( new NoVerifier());
00418       ManagedMedia tmp( handler, verifier);
00419 
00420       tmp.handler->open(url, preferred_attach_point);
00421 
00422       MediaAccessId nextId = m_impl->nextAccessId();
00423 
00424       m_impl->mediaMap[nextId] = tmp;
00425 
00426       DBG << "Opened new media access using id " << nextId
00427           << " to " << url.asString() << std::endl;
00428       return nextId;
00429     }
00430 
00431     // ---------------------------------------------------------------
00432     void
00433     MediaManager::close(MediaAccessId accessId)
00434     {
00435       MutexLock glock(g_Mutex);
00436 
00437       //
00438       // The MediaISO handler internally requests an accessId
00439       // of a "parent" handler providing the iso file.
00440       // The parent handler accessId is private to MediaISO,
00441       // but the attached media source may be shared reference.
00442       // This means, that if the accessId exactly matches the
00443       // parent handler id, close was used on uninitialized
00444       // accessId variable (or the accessId was guessed) and
00445       // the close request to this id will be rejected here.
00446       //
00447       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00448       for( ; m != m_impl->mediaMap.end(); ++m)
00449       {
00450         if( m->second.handler->dependsOnParent(accessId, true))
00451         {
00452           ZYPP_THROW(MediaIsSharedException(
00453             m->second.handler->url().asString()
00454           ));
00455         }
00456       }
00457 
00458       DBG << "Close to access handler using id "
00459           << accessId << " requested" << std::endl;
00460 
00461       ManagedMedia &ref( m_impl->findMM(accessId));
00462       ref.handler->close();
00463 
00464       m_impl->mediaMap.erase(accessId);
00465     }
00466 
00467     // ---------------------------------------------------------------
00468     bool
00469     MediaManager::isOpen(MediaAccessId accessId) const
00470     {
00471       MutexLock glock(g_Mutex);
00472 
00473       ManagedMediaMap::iterator it( m_impl->mediaMap.find(accessId));
00474       return it != m_impl->mediaMap.end() &&
00475              it->second.handler->isOpen();
00476     }
00477 
00478     // ---------------------------------------------------------------
00479     std::string
00480     MediaManager::protocol(MediaAccessId accessId) const
00481     {
00482       MutexLock glock(g_Mutex);
00483 
00484       ManagedMedia &ref( m_impl->findMM(accessId));
00485 
00486       return ref.handler->protocol();
00487     }
00488 
00489     // ---------------------------------------------------------------
00490           bool
00491     MediaManager::downloads(MediaAccessId accessId) const
00492     {
00493       MutexLock glock(g_Mutex);
00494 
00495       ManagedMedia &ref( m_impl->findMM(accessId));
00496 
00497       return ref.handler->downloads();
00498     }
00499 
00500     // ---------------------------------------------------------------
00501     // STATIC
00502     bool
00503     MediaManager::downloads(const Url &url)
00504     {
00505       return MediaAccess::downloads( url);
00506     }
00507 
00508     // ---------------------------------------------------------------
00509     Url
00510     MediaManager::url(MediaAccessId accessId) const
00511     {
00512       MutexLock glock(g_Mutex);
00513 
00514       ManagedMedia &ref( m_impl->findMM(accessId));
00515 
00516       return ref.handler->url();
00517     }
00518 
00519     // ---------------------------------------------------------------
00520     void
00521     MediaManager::addVerifier(MediaAccessId           accessId,
00522                               const MediaVerifierRef &verifier)
00523     {
00524       MutexLock glock(g_Mutex);
00525 
00526       if( !verifier)
00527         ZYPP_THROW(MediaException("Invalid verifier reference"));
00528 
00529       ManagedMedia &ref( m_impl->findMM(accessId));
00530 
00531       ref.desired = false;
00532       MediaVerifierRef(verifier).swap(ref.verifier);
00533 
00534       DBG << "MediaVerifier change: id=" << accessId << ", verifier="
00535           << verifier->info() << std::endl;
00536     }
00537 
00538     // ---------------------------------------------------------------
00539     void
00540     MediaManager::delVerifier(MediaAccessId accessId)
00541     {
00542       MutexLock glock(g_Mutex);
00543 
00544       ManagedMedia &ref( m_impl->findMM(accessId));
00545 
00546       MediaVerifierRef verifier( new NoVerifier());
00547       ref.desired  = false;
00548       ref.verifier.swap(verifier);
00549 
00550       DBG << "MediaVerifier change: id=" << accessId << ", verifier="
00551           << verifier->info() << std::endl;
00552     }
00553 
00554     // ---------------------------------------------------------------
00555     bool
00556     MediaManager::setAttachPrefix(const Pathname &attach_prefix)
00557     {
00558       MutexLock glock(g_Mutex);
00559 
00560       return MediaHandler::setAttachPrefix(attach_prefix);
00561     }
00562 
00563     // ---------------------------------------------------------------
00564     void
00565     MediaManager::attach(MediaAccessId accessId, bool next)
00566     {
00567       MutexLock glock(g_Mutex);
00568 
00569       ManagedMedia &ref( m_impl->findMM(accessId));
00570 
00571       DBG << "attach(id=" << accessId << ")" << std::endl;
00572       
00573       return ref.handler->attach(next);
00574     }
00575 
00576     // ---------------------------------------------------------------
00577     void MediaManager::attachDesiredMedia(MediaAccessId accessId)
00578     {
00579       MutexLock glock(g_Mutex);
00580 
00581       ManagedMedia &ref( m_impl->findMM(accessId));
00582       
00583       DBG << "attach(id=" << accessId << ")" << std::endl;
00584 
00585       // try first mountable/mounted device
00586       ref.handler->attach(false);
00587       try
00588       {
00589         ref.checkDesired(accessId);
00590         return;
00591       }
00592       catch (const MediaException & ex)
00593       {
00594         ZYPP_CAUGHT(ex);
00595 
00596         if (!ref.handler->hasMoreDevices())
00597           ZYPP_RETHROW(ex);
00598 
00599         if (ref.handler->isAttached())
00600           ref.handler->release();
00601       }
00602 
00603       MIL << "checkDesired(" << accessId << ") of first device failed,"
00604         " going to try others with attach(true)" << std::endl;
00605 
00606       while (ref.handler->hasMoreDevices())
00607       {
00608         try
00609         {
00610           // try to attach next device
00611           ref.handler->attach(true);
00612           ref.checkDesired(accessId);
00613           return;
00614         }
00615         catch (const MediaNotDesiredException & ex)
00616         {
00617           ZYPP_CAUGHT(ex);
00618 
00619           if (!ref.handler->hasMoreDevices())
00620           {
00621             MIL << "No desired media found after trying all detected devices." << std::endl;
00622             ZYPP_RETHROW(ex);
00623           }
00624 
00625           AttachedMedia media(ref.handler->attachedMedia());
00626           DBG << "Skipping " << media.mediaSource->asString() << ": not desired media." << std::endl;
00627 
00628           ref.handler->release();
00629         }
00630         catch (const MediaException & ex)
00631         {
00632           ZYPP_CAUGHT(ex);
00633 
00634           if (!ref.handler->hasMoreDevices())
00635             ZYPP_RETHROW(ex);
00636 
00637           AttachedMedia media(ref.handler->attachedMedia());
00638           DBG << "Skipping " << media.mediaSource->asString() << " because of exception thrown by attach(true)" << std::endl; 
00639 
00640           if (ref.handler->isAttached()) ref.handler->release();
00641         }
00642       }
00643     }
00644 
00645     // ---------------------------------------------------------------
00646     void
00647     MediaManager::release(MediaAccessId accessId, bool eject)
00648     {
00649       MutexLock glock(g_Mutex);
00650 
00651       ManagedMedia &ref( m_impl->findMM(accessId));
00652 
00653       DBG << "release(id=" << accessId
00654           << (eject ? ", eject)" : ")") << std::endl;
00655       if( eject)
00656       {
00657         //
00658         // release MediaISO handlers, that are using the one
00659         // specified with accessId, because it provides the
00660         // iso file and it will disappear now (forced release
00661         // with eject).
00662         //
00663         ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00664         for( ; m != m_impl->mediaMap.end(); ++m)
00665         {
00666           if( m->second.handler->dependsOnParent(accessId, false))
00667           {
00668             try
00669             {
00670               DBG << "Forcing release of handler depending on access id "
00671                   << accessId << std::endl;
00672               m->second.desired  = false;
00673               m->second.handler->release(!eject);
00674             }
00675             catch(const MediaException &e)
00676             {
00677               ZYPP_CAUGHT(e);
00678             }
00679           }
00680         }
00681       }
00682       ref.desired  = false;
00683       ref.handler->release(eject);
00684     }
00685 
00686     // ---------------------------------------------------------------
00687     void
00688     MediaManager::releaseAll()
00689     {
00690       MutexLock glock(g_Mutex);
00691 
00692       MIL << "Releasing all attached media" << std::endl;
00693 
00694       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
00695       for( ; m != m_impl->mediaMap.end(); ++m)
00696       {
00697         if( m->second.handler->dependsOnParent())
00698           continue;
00699 
00700         try
00701         {
00702           if(m->second.handler->isAttached())
00703           {
00704             DBG << "Releasing media id " << m->first << std::endl;
00705             m->second.desired  = false;
00706             m->second.handler->release(false);
00707           }
00708           else
00709           {
00710             DBG << "Media id " << m->first << " not attached " << std::endl;
00711           }
00712         }
00713         catch(const MediaException & e)
00714         {
00715           ZYPP_CAUGHT(e);
00716           ERR << "Failed to release media id " << m->first << std::endl;
00717         }
00718       }
00719 
00720       MIL << "Exit" << std::endl;
00721     }
00722 
00723     // ---------------------------------------------------------------
00724     void
00725     MediaManager::disconnect(MediaAccessId accessId)
00726     {
00727       MutexLock glock(g_Mutex);
00728 
00729       ManagedMedia &ref( m_impl->findMM(accessId));
00730 
00731       ref.handler->disconnect();
00732     }
00733 
00734     // ---------------------------------------------------------------
00735     bool
00736     MediaManager::isAttached(MediaAccessId accessId) const
00737     {
00738       MutexLock glock(g_Mutex);
00739 
00740       ManagedMedia &ref( m_impl->findMM(accessId));
00741 
00742       return ref.handler->isAttached();
00743     }
00744 
00745     // ---------------------------------------------------------------
00746     bool MediaManager::isSharedMedia(MediaAccessId accessId) const
00747     {
00748       MutexLock glock(g_Mutex);
00749 
00750       ManagedMedia &ref( m_impl->findMM(accessId));
00751 
00752       return ref.handler->isSharedMedia();
00753     }
00754 
00755     // ---------------------------------------------------------------
00756     bool
00757     MediaManager::isDesiredMedia(MediaAccessId accessId) const
00758     {
00759       MutexLock glock(g_Mutex);
00760 
00761       ManagedMedia &ref( m_impl->findMM(accessId));
00762 
00763       if( !ref.handler->isAttached())
00764       {
00765         ref.desired = false;
00766       }
00767       else
00768       {
00769         try {
00770           ref.desired = ref.verifier->isDesiredMedia(ref.handler);
00771         }
00772         catch(const zypp::Exception &e) {
00773           ZYPP_CAUGHT(e);
00774           ref.desired = false;
00775         }
00776       }
00777       DBG << "isDesiredMedia(" << accessId << "): "
00778           << (ref.desired ? "" : "not ")
00779           << "desired (report by "
00780           << ref.verifier->info() << ")" << std::endl;
00781       return ref.desired;
00782     }
00783 
00784     // ---------------------------------------------------------------
00785     bool
00786     MediaManager::isDesiredMedia(MediaAccessId           accessId,
00787                                  const MediaVerifierRef &verifier) const
00788     {
00789       MutexLock glock(g_Mutex);
00790 
00791       MediaVerifierRef v(verifier);
00792       if( !v)
00793         ZYPP_THROW(MediaException("Invalid verifier reference"));
00794 
00795       ManagedMedia &ref( m_impl->findMM(accessId));
00796 
00797       bool desired = false;
00798       if( ref.handler->isAttached())
00799       {
00800         try {
00801           desired = v->isDesiredMedia(ref.handler);
00802         }
00803         catch(const zypp::Exception &e) {
00804           ZYPP_CAUGHT(e);
00805           desired = false;
00806         }
00807       }
00808       DBG << "isDesiredMedia(" << accessId << "): "
00809           << (desired ? "" : "not ")
00810           << "desired (report by "
00811           << v->info() << ")" << std::endl;
00812       return desired;
00813     }
00814 
00815     // ---------------------------------------------------------------
00816     bool
00817     MediaManager::isChangeable(MediaAccessId accessId)
00818     {
00819       return url(accessId).getScheme() == "cd" || url(accessId).getScheme() == "dvd";
00820     }
00821 
00822     // ---------------------------------------------------------------
00823     Pathname
00824     MediaManager::localRoot(MediaAccessId accessId) const
00825     {
00826       MutexLock glock(g_Mutex);
00827 
00828       ManagedMedia &ref( m_impl->findMM(accessId));
00829 
00830       Pathname path;
00831       path = ref.handler->localRoot();
00832       return path;
00833     }
00834 
00835     // ---------------------------------------------------------------
00836     Pathname
00837     MediaManager::localPath(MediaAccessId accessId,
00838                             const Pathname & pathname) const
00839     {
00840       MutexLock glock(g_Mutex);
00841 
00842       ManagedMedia &ref( m_impl->findMM(accessId));
00843 
00844       Pathname path;
00845       path = ref.handler->localPath(pathname);
00846       return path;
00847     }
00848 
00849     // ---------------------------------------------------------------
00850     void
00851     MediaManager::provideFile(MediaAccessId   accessId,
00852                               const Pathname &filename,
00853                               bool            cached,
00854                               bool            checkonly) const
00855     {
00856       MutexLock glock(g_Mutex);
00857 
00858       ManagedMedia &ref( m_impl->findMM(accessId));
00859 
00860       ref.checkDesired(accessId);
00861 
00862       ref.handler->provideFile(filename, cached, checkonly);
00863     }
00864 
00865     // ---------------------------------------------------------------
00866     void
00867     MediaManager::provideDir(MediaAccessId   accessId,
00868                              const Pathname &dirname) const
00869     {
00870       MutexLock glock(g_Mutex);
00871 
00872       ManagedMedia &ref( m_impl->findMM(accessId));
00873 
00874       ref.checkDesired(accessId);
00875 
00876       ref.handler->provideDir(dirname);
00877     }
00878 
00879     // ---------------------------------------------------------------
00880     void
00881     MediaManager::provideDirTree(MediaAccessId   accessId,
00882                                  const Pathname &dirname) const
00883     {
00884       MutexLock glock(g_Mutex);
00885 
00886       ManagedMedia &ref( m_impl->findMM(accessId));
00887 
00888       ref.checkDesired(accessId);
00889 
00890       ref.handler->provideDirTree(dirname);
00891     }
00892 
00893     // ---------------------------------------------------------------
00894     void
00895     MediaManager::releaseFile(MediaAccessId   accessId,
00896                               const Pathname &filename) const
00897     {
00898       MutexLock glock(g_Mutex);
00899 
00900       ManagedMedia &ref( m_impl->findMM(accessId));
00901 
00902       ref.checkAttached(accessId);
00903 
00904       ref.handler->releaseFile(filename);
00905     }
00906 
00907     // ---------------------------------------------------------------
00908     void
00909     MediaManager::releaseDir(MediaAccessId   accessId,
00910                              const Pathname &dirname) const
00911     {
00912       MutexLock glock(g_Mutex);
00913 
00914       ManagedMedia &ref( m_impl->findMM(accessId));
00915 
00916       ref.checkAttached(accessId);
00917 
00918       ref.handler->releaseDir(dirname);
00919     }
00920 
00921 
00922     // ---------------------------------------------------------------
00923     void
00924     MediaManager::releasePath(MediaAccessId   accessId,
00925                               const Pathname &pathname) const
00926     {
00927       MutexLock glock(g_Mutex);
00928 
00929       ManagedMedia &ref( m_impl->findMM(accessId));
00930 
00931       ref.checkAttached(accessId);
00932 
00933       ref.handler->releasePath(pathname);
00934     }
00935 
00936     // ---------------------------------------------------------------
00937     void
00938     MediaManager::dirInfo(MediaAccessId           accessId,
00939                           std::list<std::string> &retlist,
00940                           const Pathname         &dirname,
00941                           bool                    dots) const
00942     {
00943       MutexLock glock(g_Mutex);
00944 
00945       ManagedMedia &ref( m_impl->findMM(accessId));
00946 
00947       // FIXME: ref.checkDesired(accessId); ???
00948       ref.checkAttached(accessId);
00949 
00950       ref.handler->dirInfo(retlist, dirname, dots);
00951     }
00952 
00953     // ---------------------------------------------------------------
00954     void
00955     MediaManager::dirInfo(MediaAccessId           accessId,
00956                           filesystem::DirContent &retlist,
00957                           const Pathname         &dirname,
00958                           bool                    dots) const
00959     {
00960       MutexLock glock(g_Mutex);
00961 
00962       ManagedMedia &ref( m_impl->findMM(accessId));
00963 
00964       // FIXME: ref.checkDesired(accessId); ???
00965       ref.checkAttached(accessId);
00966 
00967       ref.handler->dirInfo(retlist, dirname, dots);
00968     }
00969 
00970     // ---------------------------------------------------------------
00971     bool
00972     MediaManager::doesFileExist(MediaAccessId  accessId, const Pathname & filename ) const
00973     {
00974       MutexLock glock(g_Mutex);
00975       ManagedMedia &ref( m_impl->findMM(accessId));
00976 
00977       // FIXME: ref.checkDesired(accessId); ???
00978       ref.checkAttached(accessId);
00979 
00980       return ref.handler->doesFileExist(filename);
00981     }
00982     
00983     // ---------------------------------------------------------------
00984     // STATIC
00985     time_t
00986     MediaManager::getMountTableMTime()
00987     {
00988       MutexLock glock(g_Mutex);
00989       return MediaManager_Impl::getMountTableMTime();
00990     }
00991 
00992     // ---------------------------------------------------------------
00993     // STATIC
00994     MountEntries
00995     MediaManager::getMountEntries()
00996     {
00997       MutexLock glock(g_Mutex);
00998 
00999       return MediaManager_Impl::getMountEntries();
01000     }
01001 
01002     // ---------------------------------------------------------------
01003     bool
01004     MediaManager::isUseableAttachPoint(const Pathname &path,
01005                                        bool            mtab) const
01006     {
01007       if( path.empty() || path == "/" || !PathInfo(path).isDir())
01008         return false;
01009 
01010       MutexLock glock(g_Mutex);
01011 
01012       //
01013       // check against our current attach points
01014       //
01015       ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
01016       for( ; m != m_impl->mediaMap.end(); ++m)
01017       {
01018         AttachedMedia ret = m->second.handler->attachedMedia();
01019         if( ret.mediaSource && ret.attachPoint)
01020         {
01021           std::string mnt(ret.attachPoint->path.asString());
01022           std::string our(path.asString());
01023 
01024           if( our == mnt)
01025           {
01026             // already used as attach point
01027             return false;
01028           }
01029           else
01030           if( mnt.size() > our.size()   &&
01031               mnt.at(our.size()) == '/' &&
01032              !mnt.compare(0, our.size(), our))
01033           {
01034             // mountpoint is bellow of path
01035             // (would hide the content)
01036             return false;
01037           }
01038         }
01039       }
01040 
01041       if( !mtab)
01042         return true;
01043 
01044       //
01045       // check against system mount entries
01046       //
01047       MountEntries  entries( m_impl->getMountEntries());
01048       MountEntries::const_iterator e;
01049       for( e = entries.begin(); e != entries.end(); ++e)
01050       {
01051         std::string mnt(Pathname(e->dir).asString());
01052         std::string our(path.asString());
01053 
01054         if( our == mnt)
01055         {
01056           // already used as mountpoint
01057           return false;
01058         }
01059         else
01060         if( mnt.size() > our.size()   &&
01061             mnt.at(our.size()) == '/' &&
01062            !mnt.compare(0, our.size(), our))
01063         {
01064           // mountpoint is bellow of path
01065           // (would hide the content)
01066           return false;
01067         }
01068       }
01069 
01070       return true;
01071     }
01072 
01073     // ---------------------------------------------------------------
01074     AttachedMedia
01075     MediaManager::getAttachedMedia(MediaAccessId &accessId) const
01076     {
01077       MutexLock glock(g_Mutex);
01078 
01079       ManagedMedia &ref( m_impl->findMM(accessId));
01080 
01081       return ref.handler->attachedMedia();
01082     }
01083 
01084     // ---------------------------------------------------------------
01085     AttachedMedia
01086     MediaManager::findAttachedMedia(const MediaSourceRef &media) const
01087     {
01088       MutexLock glock(g_Mutex);
01089 
01090       if( !media || media->type.empty())
01091         return AttachedMedia();
01092 
01093       ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
01094       for( ; m != m_impl->mediaMap.end(); ++m)
01095       {
01096         if( !m->second.handler->isAttached())
01097           continue;
01098 
01099         AttachedMedia ret = m->second.handler->attachedMedia();
01100         if( ret.mediaSource && ret.mediaSource->equals( *media))
01101             return ret;
01102       }
01103       return AttachedMedia();
01104     }
01105 
01106     // ---------------------------------------------------------------
01107     void
01108     MediaManager::forceReleaseShared(const MediaSourceRef &media)
01109     {
01110       MutexLock glock(g_Mutex);
01111 
01112       if( !media || media->type.empty())
01113         return;
01114 
01115       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
01116       for( ; m != m_impl->mediaMap.end(); ++m)
01117       {
01118         if( !m->second.handler->isAttached())
01119           continue;
01120 
01121         AttachedMedia ret = m->second.handler->attachedMedia();
01122         if( ret.mediaSource && ret.mediaSource->equals( *media))
01123         {
01124           m->second.handler->release(false);
01125           m->second.desired  = false;
01126         }
01127       }
01128     }
01129 
01131   } // namespace media
01133 
01135 } // namespace zypp
01137 /*
01138 ** vim: set ts=2 sts=2 sw=2 ai et:
01139 */

Generated on Tue Sep 25 19:23:02 2007 for libzypp by  doxygen 1.5.3