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