1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaManager.cc
12 #include <zypp/media/MediaException.h>
13 #include <zypp/media/MediaManager.h>
14 #include <zypp/media/MediaHandler.h>
15 #include <zypp/media/Mount.h>
16 #include <zypp/thread/Mutex.h>
17 #include <zypp/thread/MutexLock.h>
19 #include <zypp/base/String.h>
20 #include <zypp/base/Logger.h>
21 #include <zypp/Pathname.h>
22 #include <zypp/PathInfo.h>
29 //////////////////////////////////////////////////////////////////////
31 { ////////////////////////////////////////////////////////////////////
33 ////////////////////////////////////////////////////////////////////
35 { //////////////////////////////////////////////////////////////////
37 using zypp::thread::Mutex;
38 using zypp::thread::MutexLock;
40 //////////////////////////////////////////////////////////////////
41 namespace // anonymous
42 { ////////////////////////////////////////////////////////////////
45 // -------------------------------------------------------------
50 // -------------------------------------------------------------
60 ManagedMedia(const ManagedMedia &m)
63 , verifier(m.verifier)
66 ManagedMedia(const MediaAccessRef &h, const MediaVerifierRef &v)
75 if( !handler->isAttached())
78 ZYPP_THROW(MediaNotAttachedException(
92 desired = verifier->isDesiredMedia(handler);
94 catch(const zypp::Exception &e) {
101 ZYPP_THROW(MediaNotDesiredException(
106 DBG << "checkDesired(): desired (report)" << std::endl;
108 DBG << "checkDesired(): desired (cached)" << std::endl;
113 MediaAccessRef handler;
114 MediaVerifierRef verifier;
118 // -------------------------------------------------------------
119 typedef std::map<MediaAccessId, ManagedMedia> ManagedMediaMap;
122 ////////////////////////////////////////////////////////////////
124 //////////////////////////////////////////////////////////////////
127 //////////////////////////////////////////////////////////////////
128 class MediaManager_Impl
131 friend class MediaManager;
133 MediaAccessId last_accessid;
134 ManagedMediaMap mediaMap;
143 MutexLock glock(g_Mutex);
147 // remove depending (iso) handlers first
148 ManagedMediaMap::iterator it;
153 for(it = mediaMap.begin(); it != mediaMap.end(); ++it)
155 if( it->second.handler->dependsOnParent())
158 it->second.handler->resetParentId();
164 // remove all other handlers
174 return ++last_accessid;
178 hasId(MediaAccessId accessId) const
180 return mediaMap.find(accessId) != mediaMap.end();
183 inline ManagedMedia &
184 findMM(MediaAccessId accessId)
186 ManagedMediaMap::iterator it( mediaMap.find(accessId));
187 if( it == mediaMap.end())
189 ZYPP_THROW(MediaNotOpenException(
190 "Invalid media access id " + str::numstring(accessId)
199 return zypp::PathInfo("/etc/mtab").mtime();
202 static inline MountEntries
205 return Mount::getEntries("/etc/mtab");
211 //////////////////////////////////////////////////////////////////
213 zypp::RW_pointer<MediaManager_Impl> MediaManager::m_impl(NULL);
216 //////////////////////////////////////////////////////////////////
217 MediaManager::MediaManager()
219 MutexLock glock(g_Mutex);
222 m_impl.reset( new MediaManager_Impl());
226 // ---------------------------------------------------------------
227 MediaManager::~MediaManager()
231 // ---------------------------------------------------------------
233 MediaManager::open(const Url &url, const Pathname &preferred_attach_point)
235 MutexLock glock(g_Mutex);
237 // create new access handler for it
238 MediaAccessRef handler( new MediaAccess());
239 MediaVerifierRef verifier( new NoVerifier());
240 ManagedMedia tmp( handler, verifier);
242 tmp.handler->open(url, preferred_attach_point);
244 MediaAccessId nextId = m_impl->nextAccessId();
246 m_impl->mediaMap[nextId] = tmp;
248 DBG << "Opened new media access using id " << nextId
249 << " to " << url.asString() << std::endl;
253 // ---------------------------------------------------------------
255 MediaManager::close(MediaAccessId accessId)
257 MutexLock glock(g_Mutex);
259 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
260 for( ; m != m_impl->mediaMap.end(); ++m)
262 if( m->second.handler->dependsOnParent(accessId))
264 // Hmm.. throw MediaIsSharedException instead?
267 DBG << "Forcing release of handler depending on access id "
268 << accessId << std::endl;
269 m->second.handler->resetParentId();
270 m->second.handler->release();
271 m->second.desired = false;
273 catch(const MediaException &e)
280 DBG << "Closing access handler with using id "
281 << accessId << std::endl;
283 ManagedMedia &ref( m_impl->findMM(accessId));
284 ref.handler->close();
286 m_impl->mediaMap.erase(accessId);
289 // ---------------------------------------------------------------
291 MediaManager::isOpen(MediaAccessId accessId) const
293 MutexLock glock(g_Mutex);
295 ManagedMediaMap::iterator it( m_impl->mediaMap.find(accessId));
296 return it != m_impl->mediaMap.end() &&
297 it->second.handler->isOpen();
300 // ---------------------------------------------------------------
302 MediaManager::protocol(MediaAccessId accessId) const
304 MutexLock glock(g_Mutex);
306 ManagedMedia &ref( m_impl->findMM(accessId));
308 return ref.handler->protocol();
311 // ---------------------------------------------------------------
313 MediaManager::downloads(MediaAccessId accessId) const
315 MutexLock glock(g_Mutex);
317 ManagedMedia &ref( m_impl->findMM(accessId));
319 return ref.handler->downloads();
322 // ---------------------------------------------------------------
325 MediaManager::downloads(const Url &url)
327 return MediaAccess::downloads( url);
330 // ---------------------------------------------------------------
332 MediaManager::url(MediaAccessId accessId) const
334 MutexLock glock(g_Mutex);
336 ManagedMedia &ref( m_impl->findMM(accessId));
338 return ref.handler->url();
341 // ---------------------------------------------------------------
343 MediaManager::addVerifier(MediaAccessId accessId,
344 const MediaVerifierRef &verifier)
346 MutexLock glock(g_Mutex);
349 ZYPP_THROW(MediaException("Invalid verifier reference"));
351 ManagedMedia &ref( m_impl->findMM(accessId));
353 MediaVerifierRef(verifier).swap(ref.verifier);
357 // ---------------------------------------------------------------
359 MediaManager::delVerifier(MediaAccessId accessId)
361 MutexLock glock(g_Mutex);
363 ManagedMedia &ref( m_impl->findMM(accessId));
365 MediaVerifierRef verifier( new NoVerifier());
366 ref.verifier.swap(verifier);
370 // ---------------------------------------------------------------
372 MediaManager::setAttachPrefix(const Pathname &attach_prefix)
374 MutexLock glock(g_Mutex);
376 return MediaHandler::setAttachPrefix(attach_prefix);
379 // ---------------------------------------------------------------
381 MediaManager::attach(MediaAccessId accessId, bool next)
383 MutexLock glock(g_Mutex);
385 ManagedMedia &ref( m_impl->findMM(accessId));
387 return ref.handler->attach(next);
390 // ---------------------------------------------------------------
392 MediaManager::release(MediaAccessId accessId, bool eject)
394 MutexLock glock(g_Mutex);
396 ManagedMedia &ref( m_impl->findMM(accessId));
401 // release MediaISO handlers, that are using the one
402 // specified with accessId, because it provides the
403 // iso file and it will disappear now (forced release).
405 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
406 for( ; m != m_impl->mediaMap.end(); ++m)
408 if( m->second.handler->dependsOnParent(accessId))
412 DBG << "Forcing release of handler depending on access id "
413 << accessId << std::endl;
414 m->second.handler->release(!eject);
415 m->second.desired = false;
417 catch(const MediaException &e)
424 ref.handler->release(eject);
428 // ---------------------------------------------------------------
430 MediaManager::disconnect(MediaAccessId accessId)
432 MutexLock glock(g_Mutex);
434 ManagedMedia &ref( m_impl->findMM(accessId));
436 ref.handler->disconnect();
439 // ---------------------------------------------------------------
441 MediaManager::isAttached(MediaAccessId accessId) const
443 MutexLock glock(g_Mutex);
445 ManagedMedia &ref( m_impl->findMM(accessId));
447 return ref.handler->isAttached();
450 // ---------------------------------------------------------------
451 bool MediaManager::isSharedMedia(MediaAccessId accessId) const
453 MutexLock glock(g_Mutex);
455 ManagedMedia &ref( m_impl->findMM(accessId));
457 return ref.handler->isSharedMedia();
460 // ---------------------------------------------------------------
462 MediaManager::isDesiredMedia(MediaAccessId accessId) const
464 MutexLock glock(g_Mutex);
466 ManagedMedia &ref( m_impl->findMM(accessId));
468 if( !ref.handler->isAttached())
475 ref.desired = ref.verifier->isDesiredMedia(ref.handler);
477 catch(const zypp::Exception &e) {
485 // ---------------------------------------------------------------
487 MediaManager::isDesiredMedia(MediaAccessId accessId,
488 const MediaVerifierRef &verifier) const
490 MutexLock glock(g_Mutex);
492 MediaVerifierRef v(verifier);
494 ZYPP_THROW(MediaException("Invalid verifier reference"));
496 ManagedMedia &ref( m_impl->findMM(accessId));
498 bool desired = false;
499 if( ref.handler->isAttached())
502 desired = v->isDesiredMedia(ref.handler);
504 catch(const zypp::Exception &e) {
512 // ---------------------------------------------------------------
514 MediaManager::localRoot(MediaAccessId accessId) const
516 MutexLock glock(g_Mutex);
518 ManagedMedia &ref( m_impl->findMM(accessId));
521 path = ref.handler->localRoot();
525 // ---------------------------------------------------------------
527 MediaManager::localPath(MediaAccessId accessId,
528 const Pathname & pathname) const
530 MutexLock glock(g_Mutex);
532 ManagedMedia &ref( m_impl->findMM(accessId));
535 path = ref.handler->localPath(pathname);
539 // ---------------------------------------------------------------
541 MediaManager::provideFile(MediaAccessId accessId,
542 const Pathname &filename,
544 bool checkonly) const
546 MutexLock glock(g_Mutex);
548 ManagedMedia &ref( m_impl->findMM(accessId));
552 ref.handler->provideFile(filename, cached, checkonly);
555 // ---------------------------------------------------------------
557 MediaManager::provideDir(MediaAccessId accessId,
558 const Pathname &dirname) const
560 MutexLock glock(g_Mutex);
562 ManagedMedia &ref( m_impl->findMM(accessId));
566 ref.handler->provideDir(dirname);
569 // ---------------------------------------------------------------
571 MediaManager::provideDirTree(MediaAccessId accessId,
572 const Pathname &dirname) const
574 MutexLock glock(g_Mutex);
576 ManagedMedia &ref( m_impl->findMM(accessId));
580 ref.handler->provideDirTree(dirname);
583 // ---------------------------------------------------------------
585 MediaManager::releaseFile(MediaAccessId accessId,
586 const Pathname &filename) const
588 MutexLock glock(g_Mutex);
590 ManagedMedia &ref( m_impl->findMM(accessId));
594 ref.handler->releaseFile(filename);
597 // ---------------------------------------------------------------
599 MediaManager::releaseDir(MediaAccessId accessId,
600 const Pathname &dirname) const
602 MutexLock glock(g_Mutex);
604 ManagedMedia &ref( m_impl->findMM(accessId));
608 ref.handler->releaseDir(dirname);
612 // ---------------------------------------------------------------
614 MediaManager::releasePath(MediaAccessId accessId,
615 const Pathname &pathname) const
617 MutexLock glock(g_Mutex);
619 ManagedMedia &ref( m_impl->findMM(accessId));
623 ref.handler->releasePath(pathname);
626 // ---------------------------------------------------------------
628 MediaManager::dirInfo(MediaAccessId accessId,
629 std::list<std::string> &retlist,
630 const Pathname &dirname,
633 MutexLock glock(g_Mutex);
635 ManagedMedia &ref( m_impl->findMM(accessId));
637 // FIXME: ref.checkDesired(); ???
640 ref.handler->dirInfo(retlist, dirname, dots);
643 // ---------------------------------------------------------------
645 MediaManager::dirInfo(MediaAccessId accessId,
646 filesystem::DirContent &retlist,
647 const Pathname &dirname,
650 MutexLock glock(g_Mutex);
652 ManagedMedia &ref( m_impl->findMM(accessId));
654 // FIXME: ref.checkDesired(); ???
657 ref.handler->dirInfo(retlist, dirname, dots);
660 // ---------------------------------------------------------------
663 MediaManager::getMountTableMTime()
665 MutexLock glock(g_Mutex);
666 return MediaManager_Impl::getMountTableMTime();
669 // ---------------------------------------------------------------
672 MediaManager::getMountEntries()
674 MutexLock glock(g_Mutex);
676 return MediaManager_Impl::getMountEntries();
679 // ---------------------------------------------------------------
681 MediaManager::isUseableAttachPoint(const Pathname &path) const
683 if( path.empty() || path == "/" || !PathInfo(path).isDir())
686 MutexLock glock(g_Mutex);
689 // check against our current attach points
691 ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
692 for( ; m != m_impl->mediaMap.end(); ++m)
694 AttachedMedia ret = m->second.handler->attachedMedia();
695 if( ret.mediaSource && ret.attachPoint)
697 std::string mnt(ret.attachPoint->path.asString());
698 std::string our(path.asString());
702 // already used as attach point
706 if( mnt.size() > our.size() &&
707 mnt.at(our.size()) == '/' &&
708 !mnt.compare(0, our.size(), our))
710 // mountpoint is bellow of path
711 // (would hide the content)
718 // check against system mount entries
720 MountEntries entries( m_impl->getMountEntries());
721 MountEntries::const_iterator e;
722 for( e = entries.begin(); e != entries.end(); ++e)
724 std::string mnt(Pathname(e->dir).asString());
725 std::string our(path.asString());
729 // already used as mountpoint
733 if( mnt.size() > our.size() &&
734 mnt.at(our.size()) == '/' &&
735 !mnt.compare(0, our.size(), our))
737 // mountpoint is bellow of path
738 // (would hide the content)
745 // ---------------------------------------------------------------
747 MediaManager::getAttachedMedia(MediaAccessId &accessId) const
749 MutexLock glock(g_Mutex);
751 ManagedMedia &ref( m_impl->findMM(accessId));
753 return ref.handler->attachedMedia();
756 // ---------------------------------------------------------------
758 MediaManager::findAttachedMedia(const MediaSourceRef &media) const
760 MutexLock glock(g_Mutex);
762 if( !media || media->type.empty())
763 return AttachedMedia();
765 ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
766 for( ; m != m_impl->mediaMap.end(); ++m)
768 if( !m->second.handler->isAttached())
771 AttachedMedia ret = m->second.handler->attachedMedia();
772 if( ret.mediaSource && ret.mediaSource->equals( *media))
775 return AttachedMedia();
778 // ---------------------------------------------------------------
780 MediaManager::forceMediaRelease(const MediaSourceRef &media)
782 MutexLock glock(g_Mutex);
784 if( !media || media->type.empty())
787 ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
788 for( ; m != m_impl->mediaMap.end(); ++m)
790 if( !m->second.handler->isAttached())
793 AttachedMedia ret = m->second.handler->attachedMedia();
794 if( ret.mediaSource && ret.mediaSource->equals( *media))
796 m->second.handler->release(false);
797 m->second.desired = false;
802 //////////////////////////////////////////////////////////////////
804 ////////////////////////////////////////////////////////////////////
806 ////////////////////////////////////////////////////////////////////
808 //////////////////////////////////////////////////////////////////////
810 ** vim: set ts=2 sts=2 sw=2 ai et: