libzypp 8.13.6
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00013 #include <iostream> 00014 #include <sstream> 00015 00016 #include "zypp/base/Logger.h" 00017 #include "zypp/base/String.h" 00018 #include "zypp/media/MediaNFS.h" 00019 #include "zypp/media/Mount.h" 00020 00021 #include <dirent.h> 00022 00023 using namespace std; 00024 00025 namespace zypp { 00026 namespace media { 00027 00029 // 00030 // CLASS NAME : MediaNFS 00031 // 00033 00035 // 00036 // 00037 // METHOD NAME : MediaNFS::MediaNFS 00038 // METHOD TYPE : Constructor 00039 // 00040 // DESCRIPTION : 00041 // 00042 MediaNFS::MediaNFS( const Url & url_r, 00043 const Pathname & attach_point_hint_r ) 00044 : MediaHandler( url_r, attach_point_hint_r, 00045 "/", // urlpath at attachpoint 00046 false ) // does_download 00047 { 00048 MIL << "MediaNFS::MediaNFS(" << url_r << ", " << attach_point_hint_r << ")" << endl; 00049 } 00050 00052 // 00053 // 00054 // METHOD NAME : MediaNFS::attachTo 00055 // METHOD TYPE : PMError 00056 // 00057 // DESCRIPTION : Asserted that not already attached, and attachPoint is a directory. 00058 // 00059 void MediaNFS::attachTo(bool next) 00060 { 00061 if(_url.getHost().empty()) 00062 ZYPP_THROW(MediaBadUrlEmptyHostException(_url)); 00063 if(next) 00064 ZYPP_THROW(MediaNotSupportedException(_url)); 00065 00066 string path = _url.getHost(); 00067 path += ':'; 00068 path += Pathname(_url.getPathName()).asString(); 00069 00070 MediaSourceRef media( new MediaSource("nfs", path)); 00071 AttachedMedia ret( findAttachedMedia( media)); 00072 00073 if( ret.mediaSource && 00074 ret.attachPoint && 00075 !ret.attachPoint->empty()) 00076 { 00077 DBG << "Using a shared media " 00078 << ret.mediaSource->name 00079 << " attached on " 00080 << ret.attachPoint->path 00081 << endl; 00082 00083 removeAttachPoint(); 00084 setAttachPoint(ret.attachPoint); 00085 setMediaSource(ret.mediaSource); 00086 return; 00087 } 00088 00089 std::string mountpoint( attachPoint().asString() ); 00090 Mount mount; 00091 00092 if( !isUseableAttachPoint(attachPoint())) 00093 { 00094 mountpoint = createAttachPoint().asString(); 00095 if( mountpoint.empty()) 00096 ZYPP_THROW( MediaBadAttachPointException(url())); 00097 setAttachPoint( mountpoint, true); 00098 } 00099 00100 std::string filesystem( _url.getScheme() ); 00101 if ( filesystem != "nfs4" && _url.getQueryParam("type") == "nfs4" ) 00102 { 00103 filesystem = "nfs4"; 00104 } 00105 00106 string options = _url.getQueryParam("mountoptions"); 00107 if(options.empty()) 00108 { 00109 options="ro"; 00110 } 00111 00112 vector<string> optionList; 00113 str::split( options, std::back_inserter(optionList), "," ); 00114 vector<string>::const_iterator it; 00115 bool contains_lock = false, contains_soft = false, 00116 contains_timeo = false, contains_hard = false; 00117 00118 for( it = optionList.begin(); it != optionList.end(); ++it ) { 00119 if ( *it == "lock" || *it == "nolock" ) contains_lock = true; 00120 else if ( *it == "soft") contains_soft = true; 00121 else if ( *it == "hard") contains_hard = true; 00122 else if ( it->find("timeo") != string::npos ) contains_timeo = true; 00123 } 00124 00125 if ( !(contains_lock && contains_soft) ) { 00126 // Add option "nolock", unless option "lock" or "unlock" is already set. 00127 // This should prevent the mount command hanging when the portmapper isn't 00128 // running. 00129 if ( !contains_lock ) { 00130 optionList.push_back( "nolock" ); 00131 } 00132 // Add options "soft,timeo=NFS_MOUNT_TIMEOUT", unless they are set 00133 // already or "hard" option is explicitly specified. This prevent 00134 // the mount command from hanging when the nfs server is not responding 00135 // and file transactions from an unresponsive to throw an error after 00136 // a short time instead of hanging forever 00137 if ( !(contains_soft || contains_hard) ) { 00138 optionList.push_back( "soft" ); 00139 if ( !contains_timeo ) { 00140 ostringstream s; 00141 s << "timeo=" << NFS_MOUNT_TIMEOUT; 00142 optionList.push_back( s.str() ); 00143 } 00144 } 00145 options = str::join( optionList, "," ); 00146 } 00147 00148 mount.mount(path,mountpoint,filesystem,options); 00149 00150 setMediaSource(media); 00151 00152 // wait for /etc/mtab update ... 00153 // (shouldn't be needed) 00154 int limit = 3; 00155 bool mountsucceeded; 00156 while( !(mountsucceeded=isAttached()) && --limit) 00157 { 00158 sleep(1); 00159 } 00160 00161 if( !mountsucceeded) 00162 { 00163 setMediaSource(MediaSourceRef()); 00164 try 00165 { 00166 mount.umount(attachPoint().asString()); 00167 } 00168 catch (const MediaException & excpt_r) 00169 { 00170 ZYPP_CAUGHT(excpt_r); 00171 } 00172 ZYPP_THROW(MediaMountException( 00173 "Unable to verify that the media was mounted", 00174 path, mountpoint 00175 )); 00176 } 00177 } 00178 00180 // 00181 // METHOD NAME : MediaNFS::isAttached 00182 // METHOD TYPE : bool 00183 // 00184 // DESCRIPTION : Override check if media is attached. 00185 // 00186 bool 00187 MediaNFS::isAttached() const 00188 { 00189 return checkAttached(true); 00190 } 00191 00193 // 00194 // 00195 // METHOD NAME : MediaNFS::releaseFrom 00196 // METHOD TYPE : void 00197 // 00198 // DESCRIPTION : Asserted that media is attached. 00199 // 00200 void MediaNFS::releaseFrom( const std::string & ejectDev ) 00201 { 00202 Mount mount; 00203 mount.umount(attachPoint().asString()); 00204 } 00205 00207 // 00208 // METHOD NAME : MediaNFS::getFile 00209 // METHOD TYPE : PMError 00210 // 00211 // DESCRIPTION : Asserted that media is attached. 00212 // 00213 void MediaNFS::getFile (const Pathname & filename) const 00214 { 00215 MediaHandler::getFile( filename );; 00216 } 00217 00219 // 00220 // METHOD NAME : MediaNFS::getDir 00221 // METHOD TYPE : PMError 00222 // 00223 // DESCRIPTION : Asserted that media is attached. 00224 // 00225 void MediaNFS::getDir( const Pathname & dirname, bool recurse_r ) const 00226 { 00227 MediaHandler::getDir( dirname, recurse_r ); 00228 } 00229 00231 // 00232 // 00233 // METHOD NAME : MediaNFS::getDirInfo 00234 // METHOD TYPE : PMError 00235 // 00236 // DESCRIPTION : Asserted that media is attached and retlist is empty. 00237 // 00238 void MediaNFS::getDirInfo( std::list<std::string> & retlist, 00239 const Pathname & dirname, bool dots ) const 00240 { 00241 MediaHandler::getDirInfo( retlist, dirname, dots ); 00242 } 00243 00245 // 00246 // 00247 // METHOD NAME : MediaNFS::getDirInfo 00248 // METHOD TYPE : PMError 00249 // 00250 // DESCRIPTION : Asserted that media is attached and retlist is empty. 00251 // 00252 void MediaNFS::getDirInfo( filesystem::DirContent & retlist, 00253 const Pathname & dirname, bool dots ) const 00254 { 00255 MediaHandler::getDirInfo( retlist, dirname, dots ); 00256 } 00257 00258 bool MediaNFS::getDoesFileExist( const Pathname & filename ) const 00259 { 00260 return MediaHandler::getDoesFileExist( filename ); 00261 } 00262 00263 00264 } // namespace media 00265 } // namespace zypp