bbca585457cca9311dcd7ba69e945a27f6fabb50
[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     void
683     MediaManager::provideFile(MediaAccessId   accessId,
684                               const Pathname &filename,
685                               const ByteCount &expectedFileSize ) 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, expectedFileSize);
694     }
695
696     // ---------------------------------------------------------------
697     void
698     MediaManager::provideFile(MediaAccessId   accessId,
699                               const Pathname &filename ) const
700     {
701       provideFile( accessId, filename, 0);
702     }
703
704     // ---------------------------------------------------------------
705     void
706     MediaManager::setDeltafile(MediaAccessId   accessId,
707                               const Pathname &filename ) const
708     {
709       MutexLock glock(g_Mutex);
710
711       ManagedMedia &ref( m_impl->findMM(accessId));
712
713       ref.checkDesired(accessId);
714
715       ref.handler->setDeltafile(filename);
716     }
717
718     // ---------------------------------------------------------------
719     void
720     MediaManager::provideDir(MediaAccessId   accessId,
721                              const Pathname &dirname) const
722     {
723       MutexLock glock(g_Mutex);
724
725       ManagedMedia &ref( m_impl->findMM(accessId));
726
727       ref.checkDesired(accessId);
728
729       ref.handler->provideDir(dirname);
730     }
731
732     // ---------------------------------------------------------------
733     void
734     MediaManager::provideDirTree(MediaAccessId   accessId,
735                                  const Pathname &dirname) const
736     {
737       MutexLock glock(g_Mutex);
738
739       ManagedMedia &ref( m_impl->findMM(accessId));
740
741       ref.checkDesired(accessId);
742
743       ref.handler->provideDirTree(dirname);
744     }
745
746     // ---------------------------------------------------------------
747     void
748     MediaManager::releaseFile(MediaAccessId   accessId,
749                               const Pathname &filename) const
750     {
751       MutexLock glock(g_Mutex);
752
753       ManagedMedia &ref( m_impl->findMM(accessId));
754
755       ref.checkAttached(accessId);
756
757       ref.handler->releaseFile(filename);
758     }
759
760     // ---------------------------------------------------------------
761     void
762     MediaManager::releaseDir(MediaAccessId   accessId,
763                              const Pathname &dirname) const
764     {
765       MutexLock glock(g_Mutex);
766
767       ManagedMedia &ref( m_impl->findMM(accessId));
768
769       ref.checkAttached(accessId);
770
771       ref.handler->releaseDir(dirname);
772     }
773
774
775     // ---------------------------------------------------------------
776     void
777     MediaManager::releasePath(MediaAccessId   accessId,
778                               const Pathname &pathname) const
779     {
780       MutexLock glock(g_Mutex);
781
782       ManagedMedia &ref( m_impl->findMM(accessId));
783
784       ref.checkAttached(accessId);
785
786       ref.handler->releasePath(pathname);
787     }
788
789     // ---------------------------------------------------------------
790     void
791     MediaManager::dirInfo(MediaAccessId           accessId,
792                           std::list<std::string> &retlist,
793                           const Pathname         &dirname,
794                           bool                    dots) const
795     {
796       MutexLock glock(g_Mutex);
797
798       ManagedMedia &ref( m_impl->findMM(accessId));
799
800       // FIXME: ref.checkDesired(accessId); ???
801       ref.checkAttached(accessId);
802
803       ref.handler->dirInfo(retlist, dirname, dots);
804     }
805
806     // ---------------------------------------------------------------
807     void
808     MediaManager::dirInfo(MediaAccessId           accessId,
809                           filesystem::DirContent &retlist,
810                           const Pathname         &dirname,
811                           bool                    dots) const
812     {
813       MutexLock glock(g_Mutex);
814
815       ManagedMedia &ref( m_impl->findMM(accessId));
816
817       // FIXME: ref.checkDesired(accessId); ???
818       ref.checkAttached(accessId);
819
820       ref.handler->dirInfo(retlist, dirname, dots);
821     }
822
823     // ---------------------------------------------------------------
824     bool
825     MediaManager::doesFileExist(MediaAccessId  accessId, const Pathname & filename ) const
826     {
827       MutexLock glock(g_Mutex);
828       ManagedMedia &ref( m_impl->findMM(accessId));
829
830       // FIXME: ref.checkDesired(accessId); ???
831       ref.checkAttached(accessId);
832
833       return ref.handler->doesFileExist(filename);
834     }
835
836     // ---------------------------------------------------------------
837     void
838     MediaManager::getDetectedDevices(MediaAccessId accessId,
839                                      std::vector<std::string> & devices,
840                                      unsigned int & index) const
841     {
842       MutexLock glock(g_Mutex);
843       ManagedMedia &ref( m_impl->findMM(accessId));
844       return ref.handler->getDetectedDevices(devices, index);
845     }
846
847     // ---------------------------------------------------------------
848     // STATIC
849     time_t
850     MediaManager::getMountTableMTime()
851     {
852       MutexLock glock(g_Mutex);
853       return MediaManager_Impl::getMountTableMTime();
854     }
855
856     // ---------------------------------------------------------------
857     // STATIC
858     MountEntries
859     MediaManager::getMountEntries()
860     {
861       MutexLock glock(g_Mutex);
862
863       return MediaManager_Impl::getMountEntries();
864     }
865
866     // ---------------------------------------------------------------
867     bool
868     MediaManager::isUseableAttachPoint(const Pathname &path,
869                                        bool            mtab) const
870     {
871       if( path.empty() || path == "/" || !PathInfo(path).isDir())
872         return false;
873
874       MutexLock glock(g_Mutex);
875
876       //
877       // check against our current attach points
878       //
879       ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
880       for( ; m != m_impl->mediaMap.end(); ++m)
881       {
882         AttachedMedia ret = m->second.handler->attachedMedia();
883         if( ret.mediaSource && ret.attachPoint)
884         {
885           std::string mnt(ret.attachPoint->path.asString());
886           std::string our(path.asString());
887
888           if( our == mnt)
889           {
890             // already used as attach point
891             return false;
892           }
893           else
894           if( mnt.size() > our.size()   &&
895               mnt.at(our.size()) == '/' &&
896              !mnt.compare(0, our.size(), our))
897           {
898             // mountpoint is bellow of path
899             // (would hide the content)
900             return false;
901           }
902         }
903       }
904
905       if( !mtab)
906         return true;
907
908       //
909       // check against system mount entries
910       //
911       MountEntries  entries( m_impl->getMountEntries());
912       MountEntries::const_iterator e;
913       for( e = entries.begin(); e != entries.end(); ++e)
914       {
915         std::string mnt(Pathname(e->dir).asString());
916         std::string our(path.asString());
917
918         if( our == mnt)
919         {
920           // already used as mountpoint
921           return false;
922         }
923         else
924         if( mnt.size() > our.size()   &&
925             mnt.at(our.size()) == '/' &&
926            !mnt.compare(0, our.size(), our))
927         {
928           // mountpoint is bellow of path
929           // (would hide the content)
930           return false;
931         }
932       }
933
934       return true;
935     }
936
937     // ---------------------------------------------------------------
938     AttachedMedia
939     MediaManager::getAttachedMedia(MediaAccessId &accessId) const
940     {
941       MutexLock glock(g_Mutex);
942
943       ManagedMedia &ref( m_impl->findMM(accessId));
944
945       return ref.handler->attachedMedia();
946     }
947
948     // ---------------------------------------------------------------
949     AttachedMedia
950     MediaManager::findAttachedMedia(const MediaSourceRef &media) const
951     {
952       MutexLock glock(g_Mutex);
953
954       if( !media || media->type.empty())
955         return AttachedMedia();
956
957       ManagedMediaMap::const_iterator m(m_impl->mediaMap.begin());
958       for( ; m != m_impl->mediaMap.end(); ++m)
959       {
960         if( !m->second.handler->isAttached())
961           continue;
962
963         AttachedMedia ret = m->second.handler->attachedMedia();
964         if( ret.mediaSource && ret.mediaSource->equals( *media))
965             return ret;
966       }
967       return AttachedMedia();
968     }
969
970     // ---------------------------------------------------------------
971     void
972     MediaManager::forceReleaseShared(const MediaSourceRef &media)
973     {
974       MutexLock glock(g_Mutex);
975
976       if( !media || media->type.empty())
977         return;
978
979       ManagedMediaMap::iterator m(m_impl->mediaMap.begin());
980       for( ; m != m_impl->mediaMap.end(); ++m)
981       {
982         if( !m->second.handler->isAttached())
983           continue;
984
985         AttachedMedia ret = m->second.handler->attachedMedia();
986         if( ret.mediaSource && ret.mediaSource->equals( *media))
987         {
988           m->second.handler->release();
989           m->second.desired  = false;
990         }
991       }
992     }
993
994     //////////////////////////////////////////////////////////////////
995   } // namespace media
996   ////////////////////////////////////////////////////////////////////
997
998   ////////////////////////////////////////////////////////////////////
999 } // namespace zypp
1000 //////////////////////////////////////////////////////////////////////
1001 /*
1002 ** vim: set ts=2 sts=2 sw=2 ai et:
1003 */