Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / media / MediaManager.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaManager.cc
10  *
11 */
12 #include <map>
13 #include <list>
14 #include <iostream>
15 #include <typeinfo>
16
17 #include "zypp/media/MediaException.h"
18 #include "zypp/media/MediaManager.h"
19 #include "zypp/media/MediaHandler.h"
20 #include "zypp/media/Mount.h"
21 #include "zypp/thread/Mutex.h"
22 #include "zypp/thread/MutexLock.h"
23
24 #include "zypp/base/String.h"
25 #include "zypp/base/Logger.h"
26 #include "zypp/Pathname.h"
27 #include "zypp/PathInfo.h"
28
29 //////////////////////////////////////////////////////////////////////
30 namespace zypp
31 { ////////////////////////////////////////////////////////////////////
32
33   ////////////////////////////////////////////////////////////////////
34   namespace media
35   { //////////////////////////////////////////////////////////////////
36
37     using zypp::thread::Mutex;
38     using zypp::thread::MutexLock;
39
40     //////////////////////////////////////////////////////////////////
41     namespace // anonymous
42     { ////////////////////////////////////////////////////////////////
43
44
45       // -------------------------------------------------------------
46       // STATIC
47       static Mutex  g_Mutex;
48
49
50       // -------------------------------------------------------------
51       struct ManagedMedia
52       {
53         ~ManagedMedia()
54         {}
55
56         ManagedMedia()
57           : desired (false)
58         {}
59
60         ManagedMedia(const ManagedMedia &m)
61           : desired (m.desired)
62           , handler (m.handler)
63           , verifier(m.verifier)
64         {}
65
66         ManagedMedia(const MediaAccessRef &h, const MediaVerifierRef &v)
67           : desired (false)
68           , handler (h)
69           , verifier(v)
70         {}
71
72         inline void
73         checkAttached(MediaAccessId id)
74         {
75           if( !handler->isAttached())
76           {
77             DBG << "checkAttached(" << id << ") not attached" << std::endl;
78             desired = false;
79             ZYPP_THROW(MediaNotAttachedException(
80               handler->url()
81             ));
82           }
83         }
84
85         inline void
86         checkDesired(MediaAccessId id)
87         {
88           checkAttached(id);
89
90           if( !desired)
91           {
92             try {
93               desired = verifier->isDesiredMedia(handler);
94             }
95             catch(const zypp::Exception &e) {
96               ZYPP_CAUGHT(e);
97               desired = false;
98             }
99
100             if( !desired)
101             {
102               DBG << "checkDesired(" << id << "): not desired (report by "
103                   << verifier->info() << ")" << std::endl;
104               ZYPP_THROW(MediaNotDesiredException(
105                 handler->url()
106               ));
107             }
108
109             DBG << "checkDesired(" << id << "): desired (report by "
110                 << verifier->info() << ")" << std::endl;
111           } else {
112             DBG << "checkDesired(" << id << "): desired (cached)" << std::endl;
113           }
114         }
115
116         bool             desired;
117         MediaAccessRef   handler;
118         MediaVerifierRef verifier;
119       };
120
121
122       // -------------------------------------------------------------
123       typedef std::map<MediaAccessId, ManagedMedia> ManagedMediaMap;
124
125       ////////////////////////////////////////////////////////////////
126     } // anonymous
127     //////////////////////////////////////////////////////////////////
128
129
130     //////////////////////////////////////////////////////////////////
131     std::string
132     MediaVerifierBase::info() const
133     {
134       return std::string(typeid((*this)).name());
135     }
136
137
138     //////////////////////////////////////////////////////////////////
139     std::string
140     NoVerifier::info() const
141     {
142       return std::string("zypp::media::NoVerifier");
143     }
144
145
146     //////////////////////////////////////////////////////////////////
147     class MediaManager_Impl
148     {
149     private:
150       friend class MediaManager;
151
152       MediaAccessId       last_accessid;
153       ManagedMediaMap     mediaMap;
154
155       MediaManager_Impl()
156         : last_accessid(0)
157       {}
158
159     public:
160       ~MediaManager_Impl()
161       {
162         MutexLock glock(g_Mutex);
163
164         try
165         {
166           // remove depending (iso) handlers first
167           ManagedMediaMap::iterator it;
168           bool found;
169           do
170           {
171             found = false;
172             for(it = mediaMap.begin(); it != mediaMap.end(); /**/)
173             {
174               if( it->second.handler->dependsOnParent())
175               {
176                 found = true;
177                 // let it forget its parent, we will
178                 // destroy it later (in clear())...
179                 it->second.handler->resetParentId();
180                 mediaMap.erase( it++ ); // postfix! Incrementing before erase
181               } else {
182                 ++it;
183               }
184             }
185           } while(found);
186
187           // remove all other handlers
188           mediaMap.clear();
189         }
190         catch( ... )
191         {}
192       }
193
194       inline MediaAccessId
195       nextAccessId()
196       {
197         return ++last_accessid;
198       }
199
200       inline bool
201       hasId(MediaAccessId accessId) const
202       {
203         return mediaMap.find(accessId) != mediaMap.end();
204       }
205
206       inline ManagedMedia &
207       findMM(MediaAccessId accessId)
208       {
209         ManagedMediaMap::iterator it( mediaMap.find(accessId));
210         if( it == mediaMap.end())
211         {
212           ZYPP_THROW(MediaNotOpenException(
213             "Invalid media access id " + str::numstring(accessId)
214           ));
215         }
216         return it->second;
217       }
218
219       static inline time_t
220       getMountTableMTime()
221       {
222         time_t mtime = zypp::PathInfo("/etc/mtab").mtime();
223         if( mtime <= 0)
224         {
225           WAR << "Failed to retrieve modification time of '/etc/mtab'"
226               << std::endl;
227         }
228         return mtime;
229       }
230
231       static inline MountEntries
232       getMountEntries()
233       {
234         return Mount::getEntries();
235       }
236
237     };
238
239
240     //////////////////////////////////////////////////////////////////
241     // STATIC
242     zypp::RW_pointer<MediaManager_Impl> MediaManager::m_impl;
243
244
245     //////////////////////////////////////////////////////////////////
246     MediaManager::MediaManager()
247     {
248       MutexLock glock(g_Mutex);
249       if( !m_impl)
250       {
251         m_impl.reset( new MediaManager_Impl());
252       }
253     }
254
255     // ---------------------------------------------------------------
256     MediaManager::~MediaManager()
257     {
258     }
259
260     // ---------------------------------------------------------------
261     MediaAccessId
262     MediaManager::open(const Url &url, const Pathname &preferred_attach_point)
263     {
264       MutexLock glock(g_Mutex);
265
266       // create new access handler for it
267       MediaAccessRef handler( new MediaAccess());
268       MediaVerifierRef verifier( new NoVerifier());
269       ManagedMedia tmp( handler, verifier);
270
271       tmp.handler->open(url, preferred_attach_point);
272
273       MediaAccessId nextId = m_impl->nextAccessId();
274
275       m_impl->mediaMap[nextId] = tmp;
276
277       DBG << "Opened new media access using id " << nextId
278           << " to " << url.asString() << std::endl;
279       return nextId;
280     }
281
282     // ---------------------------------------------------------------
283     void
284     MediaManager::close(MediaAccessId accessId)
285     {
286       MutexLock glock(g_Mutex);
287
288       //
289       // The MediaISO handler internally requests an accessId
290       // of a "parent" handler providing the iso file.
291       // The parent handler accessId is private to MediaISO,
292       // but the attached media source may be shared reference.
293       // This means, that if the accessId exactly matches the
294       // parent handler id, close was used on uninitialized
295       // accessId variable (or the accessId was guessed) and
296       // the close request to this id will be rejected here.
297       //
298       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
299       for( ; m != m_impl->mediaMap.end(); ++m)
300       {
301         if( m->second.handler->dependsOnParent(accessId, true))
302         {
303           ZYPP_THROW(MediaIsSharedException(
304             m->second.handler->url().asString()
305           ));
306         }
307       }
308
309       DBG << "Close to access handler using id "
310           << accessId << " requested" << std::endl;
311
312       ManagedMedia &ref( m_impl->findMM(accessId));
313       ref.handler->close();
314
315       m_impl->mediaMap.erase(accessId);
316     }
317
318     // ---------------------------------------------------------------
319     bool
320     MediaManager::isOpen(MediaAccessId accessId) const
321     {
322       MutexLock glock(g_Mutex);
323
324       ManagedMediaMap::iterator it( m_impl->mediaMap.find(accessId));
325       return it != m_impl->mediaMap.end() &&
326              it->second.handler->isOpen();
327     }
328
329     // ---------------------------------------------------------------
330     std::string
331     MediaManager::protocol(MediaAccessId accessId) const
332     {
333       MutexLock glock(g_Mutex);
334
335       ManagedMedia &ref( m_impl->findMM(accessId));
336
337       return ref.handler->protocol();
338     }
339
340     // ---------------------------------------------------------------
341           bool
342     MediaManager::downloads(MediaAccessId accessId) const
343     {
344       MutexLock glock(g_Mutex);
345
346       ManagedMedia &ref( m_impl->findMM(accessId));
347
348       return ref.handler->downloads();
349     }
350
351     // ---------------------------------------------------------------
352     Url
353     MediaManager::url(MediaAccessId accessId) const
354     {
355       MutexLock glock(g_Mutex);
356
357       ManagedMedia &ref( m_impl->findMM(accessId));
358
359       return ref.handler->url();
360     }
361
362     // ---------------------------------------------------------------
363     void
364     MediaManager::addVerifier(MediaAccessId           accessId,
365                               const MediaVerifierRef &verifier)
366     {
367       MutexLock glock(g_Mutex);
368
369       if( !verifier)
370         ZYPP_THROW(MediaException("Invalid verifier reference"));
371
372       ManagedMedia &ref( m_impl->findMM(accessId));
373
374       ref.desired = false;
375       MediaVerifierRef(verifier).swap(ref.verifier);
376
377       DBG << "MediaVerifier change: id=" << accessId << ", verifier="
378           << verifier->info() << std::endl;
379     }
380
381     // ---------------------------------------------------------------
382     void
383     MediaManager::delVerifier(MediaAccessId accessId)
384     {
385       MutexLock glock(g_Mutex);
386
387       ManagedMedia &ref( m_impl->findMM(accessId));
388
389       MediaVerifierRef verifier( new NoVerifier());
390       ref.desired  = false;
391       ref.verifier.swap(verifier);
392
393       DBG << "MediaVerifier change: id=" << accessId << ", verifier="
394           << verifier->info() << std::endl;
395     }
396
397     // ---------------------------------------------------------------
398     bool
399     MediaManager::setAttachPrefix(const Pathname &attach_prefix)
400     {
401       MutexLock glock(g_Mutex);
402
403       return MediaHandler::setAttachPrefix(attach_prefix);
404     }
405
406     // ---------------------------------------------------------------
407     void MediaManager::attach(MediaAccessId accessId)
408     {
409       MutexLock glock(g_Mutex);
410
411       ManagedMedia &ref( m_impl->findMM(accessId));
412
413       DBG << "attach(id=" << accessId << ")" << std::endl;
414
415       // try first mountable/mounted device
416       ref.handler->attach(false);
417       try
418       {
419         ref.checkDesired(accessId);
420         return;
421       }
422       catch (const MediaException & ex)
423       {
424         ZYPP_CAUGHT(ex);
425
426         if (!ref.handler->hasMoreDevices())
427           ZYPP_RETHROW(ex);
428
429         if (ref.handler->isAttached())
430           ref.handler->release();
431       }
432
433       MIL << "checkDesired(" << accessId << ") of first device failed,"
434         " going to try others with attach(true)" << std::endl;
435
436       while (ref.handler->hasMoreDevices())
437       {
438         try
439         {
440           // try to attach next device
441           ref.handler->attach(true);
442           ref.checkDesired(accessId);
443           return;
444         }
445         catch (const MediaNotDesiredException & ex)
446         {
447           ZYPP_CAUGHT(ex);
448
449           if (!ref.handler->hasMoreDevices())
450           {
451             MIL << "No desired media found after trying all detected devices." << std::endl;
452             ZYPP_RETHROW(ex);
453           }
454
455           AttachedMedia media(ref.handler->attachedMedia());
456           DBG << "Skipping " << media.mediaSource->asString() << ": not desired media." << std::endl;
457
458           ref.handler->release();
459         }
460         catch (const MediaException & ex)
461         {
462           ZYPP_CAUGHT(ex);
463
464           if (!ref.handler->hasMoreDevices())
465             ZYPP_RETHROW(ex);
466
467           AttachedMedia media(ref.handler->attachedMedia());
468           DBG << "Skipping " << media.mediaSource->asString() << " because of exception thrown by attach(true)" << std::endl;
469
470           if (ref.handler->isAttached()) ref.handler->release();
471         }
472       }
473     }
474
475     // ---------------------------------------------------------------
476     void
477     MediaManager::release(MediaAccessId accessId, const std::string & ejectDev)
478     {
479       MutexLock glock(g_Mutex);
480
481       ManagedMedia &ref( m_impl->findMM(accessId));
482
483       DBG << "release(id=" << accessId;
484       if (!ejectDev.empty())
485         DBG << ", " << ejectDev;
486       DBG << ")" << std::endl;
487
488       if(!ejectDev.empty())
489       {
490         //
491         // release MediaISO handlers, that are using the one
492         // specified with accessId, because it provides the
493         // iso file and it will disappear now (forced release
494         // with eject).
495         //
496         ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
497         for( ; m != m_impl->mediaMap.end(); ++m)
498         {
499           if( m->second.handler->dependsOnParent(accessId, false))
500           {
501             try
502             {
503               DBG << "Forcing release of handler depending on access id "
504                   << accessId << std::endl;
505               m->second.desired  = false;
506               m->second.handler->release();
507             }
508             catch(const MediaException &e)
509             {
510               ZYPP_CAUGHT(e);
511             }
512           }
513         }
514       }
515       ref.desired  = false;
516       ref.handler->release(ejectDev);
517     }
518
519     // ---------------------------------------------------------------
520     void
521     MediaManager::releaseAll()
522     {
523       MutexLock glock(g_Mutex);
524
525       MIL << "Releasing all attached media" << std::endl;
526
527       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
528       for( ; m != m_impl->mediaMap.end(); ++m)
529       {
530         if( m->second.handler->dependsOnParent())
531           continue;
532
533         try
534         {
535           if(m->second.handler->isAttached())
536           {
537             DBG << "Releasing media id " << m->first << std::endl;
538             m->second.desired  = false;
539             m->second.handler->release();
540           }
541           else
542           {
543             DBG << "Media id " << m->first << " not attached " << std::endl;
544           }
545         }
546         catch(const MediaException & e)
547         {
548           ZYPP_CAUGHT(e);
549           ERR << "Failed to release media id " << m->first << std::endl;
550         }
551       }
552
553       MIL << "Exit" << std::endl;
554     }
555
556     // ---------------------------------------------------------------
557     void
558     MediaManager::disconnect(MediaAccessId accessId)
559     {
560       MutexLock glock(g_Mutex);
561
562       ManagedMedia &ref( m_impl->findMM(accessId));
563
564       ref.handler->disconnect();
565     }
566
567     // ---------------------------------------------------------------
568     bool
569     MediaManager::isAttached(MediaAccessId accessId) const
570     {
571       MutexLock glock(g_Mutex);
572
573       ManagedMedia &ref( m_impl->findMM(accessId));
574
575       return ref.handler->isAttached();
576     }
577
578     // ---------------------------------------------------------------
579     bool MediaManager::isSharedMedia(MediaAccessId accessId) const
580     {
581       MutexLock glock(g_Mutex);
582
583       ManagedMedia &ref( m_impl->findMM(accessId));
584
585       return ref.handler->isSharedMedia();
586     }
587
588     // ---------------------------------------------------------------
589     bool
590     MediaManager::isDesiredMedia(MediaAccessId accessId) const
591     {
592       MutexLock glock(g_Mutex);
593
594       ManagedMedia &ref( m_impl->findMM(accessId));
595
596       if( !ref.handler->isAttached())
597       {
598         ref.desired = false;
599       }
600       else
601       {
602         try {
603           ref.desired = ref.verifier->isDesiredMedia(ref.handler);
604         }
605         catch(const zypp::Exception &e) {
606           ZYPP_CAUGHT(e);
607           ref.desired = false;
608         }
609       }
610       DBG << "isDesiredMedia(" << accessId << "): "
611           << (ref.desired ? "" : "not ")
612           << "desired (report by "
613           << ref.verifier->info() << ")" << std::endl;
614       return ref.desired;
615     }
616
617     // ---------------------------------------------------------------
618     bool
619     MediaManager::isDesiredMedia(MediaAccessId           accessId,
620                                  const MediaVerifierRef &verifier) const
621     {
622       MutexLock glock(g_Mutex);
623
624       MediaVerifierRef v(verifier);
625       if( !v)
626         ZYPP_THROW(MediaException("Invalid verifier reference"));
627
628       ManagedMedia &ref( m_impl->findMM(accessId));
629
630       bool desired = false;
631       if( ref.handler->isAttached())
632       {
633         try {
634           desired = v->isDesiredMedia(ref.handler);
635         }
636         catch(const zypp::Exception &e) {
637           ZYPP_CAUGHT(e);
638           desired = false;
639         }
640       }
641       DBG << "isDesiredMedia(" << accessId << "): "
642           << (desired ? "" : "not ")
643           << "desired (report by "
644           << v->info() << ")" << std::endl;
645       return desired;
646     }
647
648     // ---------------------------------------------------------------
649     bool
650     MediaManager::isChangeable(MediaAccessId accessId)
651     {
652       return url(accessId).getScheme() == "cd" || url(accessId).getScheme() == "dvd";
653     }
654
655     // ---------------------------------------------------------------
656     Pathname
657     MediaManager::localRoot(MediaAccessId accessId) const
658     {
659       MutexLock glock(g_Mutex);
660
661       ManagedMedia &ref( m_impl->findMM(accessId));
662
663       Pathname path;
664       path = ref.handler->localRoot();
665       return path;
666     }
667
668     // ---------------------------------------------------------------
669     Pathname
670     MediaManager::localPath(MediaAccessId accessId,
671                             const Pathname & pathname) const
672     {
673       MutexLock glock(g_Mutex);
674
675       ManagedMedia &ref( m_impl->findMM(accessId));
676
677       Pathname path;
678       path = ref.handler->localPath(pathname);
679       return path;
680     }
681
682     // ---------------------------------------------------------------
683     void
684     MediaManager::provideFile(MediaAccessId   accessId,
685                               const Pathname &filename ) const
686     {
687       MutexLock glock(g_Mutex);
688
689       ManagedMedia &ref( m_impl->findMM(accessId));
690
691       ref.checkDesired(accessId);
692
693       ref.handler->provideFile(filename);
694     }
695
696     // ---------------------------------------------------------------
697     void
698     MediaManager::setDeltafile(MediaAccessId   accessId,
699                               const Pathname &filename ) const
700     {
701       MutexLock glock(g_Mutex);
702
703       ManagedMedia &ref( m_impl->findMM(accessId));
704
705       ref.checkDesired(accessId);
706
707       ref.handler->setDeltafile(filename);
708     }
709
710     // ---------------------------------------------------------------
711     void
712     MediaManager::provideDir(MediaAccessId   accessId,
713                              const Pathname &dirname) const
714     {
715       MutexLock glock(g_Mutex);
716
717       ManagedMedia &ref( m_impl->findMM(accessId));
718
719       ref.checkDesired(accessId);
720
721       ref.handler->provideDir(dirname);
722     }
723
724     // ---------------------------------------------------------------
725     void
726     MediaManager::provideDirTree(MediaAccessId   accessId,
727                                  const Pathname &dirname) const
728     {
729       MutexLock glock(g_Mutex);
730
731       ManagedMedia &ref( m_impl->findMM(accessId));
732
733       ref.checkDesired(accessId);
734
735       ref.handler->provideDirTree(dirname);
736     }
737
738     // ---------------------------------------------------------------
739     void
740     MediaManager::releaseFile(MediaAccessId   accessId,
741                               const Pathname &filename) const
742     {
743       MutexLock glock(g_Mutex);
744
745       ManagedMedia &ref( m_impl->findMM(accessId));
746
747       ref.checkAttached(accessId);
748
749       ref.handler->releaseFile(filename);
750     }
751
752     // ---------------------------------------------------------------
753     void
754     MediaManager::releaseDir(MediaAccessId   accessId,
755                              const Pathname &dirname) const
756     {
757       MutexLock glock(g_Mutex);
758
759       ManagedMedia &ref( m_impl->findMM(accessId));
760
761       ref.checkAttached(accessId);
762
763       ref.handler->releaseDir(dirname);
764     }
765
766
767     // ---------------------------------------------------------------
768     void
769     MediaManager::releasePath(MediaAccessId   accessId,
770                               const Pathname &pathname) const
771     {
772       MutexLock glock(g_Mutex);
773
774       ManagedMedia &ref( m_impl->findMM(accessId));
775
776       ref.checkAttached(accessId);
777
778       ref.handler->releasePath(pathname);
779     }
780
781     // ---------------------------------------------------------------
782     void
783     MediaManager::dirInfo(MediaAccessId           accessId,
784                           std::list<std::string> &retlist,
785                           const Pathname         &dirname,
786                           bool                    dots) const
787     {
788       MutexLock glock(g_Mutex);
789
790       ManagedMedia &ref( m_impl->findMM(accessId));
791
792       // FIXME: ref.checkDesired(accessId); ???
793       ref.checkAttached(accessId);
794
795       ref.handler->dirInfo(retlist, dirname, dots);
796     }
797
798     // ---------------------------------------------------------------
799     void
800     MediaManager::dirInfo(MediaAccessId           accessId,
801                           filesystem::DirContent &retlist,
802                           const Pathname         &dirname,
803                           bool                    dots) const
804     {
805       MutexLock glock(g_Mutex);
806
807       ManagedMedia &ref( m_impl->findMM(accessId));
808
809       // FIXME: ref.checkDesired(accessId); ???
810       ref.checkAttached(accessId);
811
812       ref.handler->dirInfo(retlist, dirname, dots);
813     }
814
815     // ---------------------------------------------------------------
816     bool
817     MediaManager::doesFileExist(MediaAccessId  accessId, const Pathname & filename ) const
818     {
819       MutexLock glock(g_Mutex);
820       ManagedMedia &ref( m_impl->findMM(accessId));
821
822       // FIXME: ref.checkDesired(accessId); ???
823       ref.checkAttached(accessId);
824
825       return ref.handler->doesFileExist(filename);
826     }
827
828     // ---------------------------------------------------------------
829     void
830     MediaManager::getDetectedDevices(MediaAccessId accessId,
831                                      std::vector<std::string> & devices,
832                                      unsigned int & index) const
833     {
834       MutexLock glock(g_Mutex);
835       ManagedMedia &ref( m_impl->findMM(accessId));
836       return ref.handler->getDetectedDevices(devices, index);
837     }
838
839     // ---------------------------------------------------------------
840     // STATIC
841     time_t
842     MediaManager::getMountTableMTime()
843     {
844       MutexLock glock(g_Mutex);
845       return MediaManager_Impl::getMountTableMTime();
846     }
847
848     // ---------------------------------------------------------------
849     // STATIC
850     MountEntries
851     MediaManager::getMountEntries()
852     {
853       MutexLock glock(g_Mutex);
854
855       return MediaManager_Impl::getMountEntries();
856     }
857
858     // ---------------------------------------------------------------
859     bool
860     MediaManager::isUseableAttachPoint(const Pathname &path,
861                                        bool            mtab) const
862     {
863       if( path.empty() || path == "/" || !PathInfo(path).isDir())
864         return false;
865
866       MutexLock glock(g_Mutex);
867
868       //
869       // check against our current attach points
870       //
871       ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
872       for( ; m != m_impl->mediaMap.end(); ++m)
873       {
874         AttachedMedia ret = m->second.handler->attachedMedia();
875         if( ret.mediaSource && ret.attachPoint)
876         {
877           std::string mnt(ret.attachPoint->path.asString());
878           std::string our(path.asString());
879
880           if( our == mnt)
881           {
882             // already used as attach point
883             return false;
884           }
885           else
886           if( mnt.size() > our.size()   &&
887               mnt.at(our.size()) == '/' &&
888              !mnt.compare(0, our.size(), our))
889           {
890             // mountpoint is bellow of path
891             // (would hide the content)
892             return false;
893           }
894         }
895       }
896
897       if( !mtab)
898         return true;
899
900       //
901       // check against system mount entries
902       //
903       MountEntries  entries( m_impl->getMountEntries());
904       MountEntries::const_iterator e;
905       for( e = entries.begin(); e != entries.end(); ++e)
906       {
907         std::string mnt(Pathname(e->dir).asString());
908         std::string our(path.asString());
909
910         if( our == mnt)
911         {
912           // already used as mountpoint
913           return false;
914         }
915         else
916         if( mnt.size() > our.size()   &&
917             mnt.at(our.size()) == '/' &&
918            !mnt.compare(0, our.size(), our))
919         {
920           // mountpoint is bellow of path
921           // (would hide the content)
922           return false;
923         }
924       }
925
926       return true;
927     }
928
929     // ---------------------------------------------------------------
930     AttachedMedia
931     MediaManager::getAttachedMedia(MediaAccessId &accessId) const
932     {
933       MutexLock glock(g_Mutex);
934
935       ManagedMedia &ref( m_impl->findMM(accessId));
936
937       return ref.handler->attachedMedia();
938     }
939
940     // ---------------------------------------------------------------
941     AttachedMedia
942     MediaManager::findAttachedMedia(const MediaSourceRef &media) const
943     {
944       MutexLock glock(g_Mutex);
945
946       if( !media || media->type.empty())
947         return AttachedMedia();
948
949       ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
950       for( ; m != m_impl->mediaMap.end(); ++m)
951       {
952         if( !m->second.handler->isAttached())
953           continue;
954
955         AttachedMedia ret = m->second.handler->attachedMedia();
956         if( ret.mediaSource && ret.mediaSource->equals( *media))
957             return ret;
958       }
959       return AttachedMedia();
960     }
961
962     // ---------------------------------------------------------------
963     void
964     MediaManager::forceReleaseShared(const MediaSourceRef &media)
965     {
966       MutexLock glock(g_Mutex);
967
968       if( !media || media->type.empty())
969         return;
970
971       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
972       for( ; m != m_impl->mediaMap.end(); ++m)
973       {
974         if( !m->second.handler->isAttached())
975           continue;
976
977         AttachedMedia ret = m->second.handler->attachedMedia();
978         if( ret.mediaSource && ret.mediaSource->equals( *media))
979         {
980           m->second.handler->release();
981           m->second.desired  = false;
982         }
983       }
984     }
985
986     //////////////////////////////////////////////////////////////////
987   } // namespace media
988   ////////////////////////////////////////////////////////////////////
989
990   ////////////////////////////////////////////////////////////////////
991 } // namespace zypp
992 //////////////////////////////////////////////////////////////////////
993 /*
994 ** vim: set ts=2 sts=2 sw=2 ai et:
995 */