libzypp  15.28.6
MediaNFS.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
13 #include <iostream>
14 #include <sstream>
15 
16 #include "zypp/base/Logger.h"
17 #include "zypp/base/String.h"
18 #include "zypp/media/MediaNFS.h"
19 #include "zypp/media/Mount.h"
20 
21 #include <dirent.h>
22 
23 using namespace std;
24 
25 namespace zypp {
26  namespace media {
27 
29  //
30  // CLASS NAME : MediaNFS
31  //
33 
35  //
36  //
37  // METHOD NAME : MediaNFS::MediaNFS
38  // METHOD TYPE : Constructor
39  //
40  // DESCRIPTION :
41  //
42  MediaNFS::MediaNFS( const Url & url_r,
43  const Pathname & attach_point_hint_r )
44  : MediaHandler( url_r, attach_point_hint_r,
45  "/", // urlpath at attachpoint
46  false ) // does_download
47  {
48  MIL << "MediaNFS::MediaNFS(" << url_r << ", " << attach_point_hint_r << ")" << endl;
49  }
50 
52  //
53  //
54  // METHOD NAME : MediaNFS::attachTo
55  // METHOD TYPE : PMError
56  //
57  // DESCRIPTION : Asserted that not already attached, and attachPoint is a directory.
58  //
59  void MediaNFS::attachTo(bool next)
60  {
61  if(_url.getHost().empty())
63  if(next)
65 
66  string path = _url.getHost();
67  path += ':';
68  path += Pathname(_url.getPathName()).asString();
69 
70  MediaSourceRef media( new MediaSource("nfs", path));
71  AttachedMedia ret( findAttachedMedia( media));
72 
73  if( ret.mediaSource &&
74  ret.attachPoint &&
75  !ret.attachPoint->empty())
76  {
77  DBG << "Using a shared media "
78  << ret.mediaSource->name
79  << " attached on "
80  << ret.attachPoint->path
81  << endl;
82 
86  return;
87  }
88 
89  std::string mountpoint( attachPoint().asString() );
90  Mount mount;
91 
93  {
94  mountpoint = createAttachPoint().asString();
95  if( mountpoint.empty())
97  setAttachPoint( mountpoint, true);
98  }
99 
100  std::string filesystem( _url.getScheme() );
101  if ( filesystem != "nfs4" && _url.getQueryParam("type") == "nfs4" )
102  {
103  filesystem = "nfs4";
104  }
105 
106  string options = _url.getQueryParam("mountoptions");
107  if(options.empty())
108  {
109  options="ro";
110  }
111 
112  vector<string> optionList;
113  str::split( options, std::back_inserter(optionList), "," );
114  vector<string>::const_iterator it;
115  bool contains_lock = false, contains_soft = false,
116  contains_timeo = false, contains_hard = false;
117 
118  for( it = optionList.begin(); it != optionList.end(); ++it ) {
119  if ( *it == "lock" || *it == "nolock" ) contains_lock = true;
120  else if ( *it == "soft") contains_soft = true;
121  else if ( *it == "hard") contains_hard = true;
122  else if ( it->find("timeo") != string::npos ) contains_timeo = true;
123  }
124 
125  if ( !(contains_lock && contains_soft) ) {
126  // Add option "nolock", unless option "lock" or "unlock" is already set.
127  // This should prevent the mount command hanging when the portmapper isn't
128  // running.
129  if ( !contains_lock ) {
130  optionList.push_back( "nolock" );
131  }
132  // Add options "soft,timeo=NFS_MOUNT_TIMEOUT", unless they are set
133  // already or "hard" option is explicitly specified. This prevent
134  // the mount command from hanging when the nfs server is not responding
135  // and file transactions from an unresponsive to throw an error after
136  // a short time instead of hanging forever
137  if ( !(contains_soft || contains_hard) ) {
138  optionList.push_back( "soft" );
139  if ( !contains_timeo ) {
140  ostringstream s;
141  s << "timeo=" << NFS_MOUNT_TIMEOUT;
142  optionList.push_back( s.str() );
143  }
144  }
145  options = str::join( optionList, "," );
146  }
147 
148  mount.mount(path,mountpoint,filesystem,options);
149 
150  setMediaSource(media);
151 
152  // wait for /etc/mtab update ...
153  // (shouldn't be needed)
154  int limit = 3;
155  bool mountsucceeded;
156  while( !(mountsucceeded=isAttached()) && --limit)
157  {
158  sleep(1);
159  }
160 
161  if( !mountsucceeded)
162  {
164  try
165  {
166  mount.umount(attachPoint().asString());
167  }
168  catch (const MediaException & excpt_r)
169  {
170  ZYPP_CAUGHT(excpt_r);
171  }
173  "Unable to verify that the media was mounted",
174  path, mountpoint
175  ));
176  }
177  }
178 
180  //
181  // METHOD NAME : MediaNFS::isAttached
182  // METHOD TYPE : bool
183  //
184  // DESCRIPTION : Override check if media is attached.
185  //
186  bool
188  {
189  return checkAttached(true);
190  }
191 
193  //
194  //
195  // METHOD NAME : MediaNFS::releaseFrom
196  // METHOD TYPE : void
197  //
198  // DESCRIPTION : Asserted that media is attached.
199  //
200  void MediaNFS::releaseFrom( const std::string & ejectDev )
201  {
202  Mount mount;
203  mount.umount(attachPoint().asString());
204  }
205 
207  //
208  // METHOD NAME : MediaNFS::getFile
209  // METHOD TYPE : PMError
210  //
211  // DESCRIPTION : Asserted that media is attached.
212  //
213  void MediaNFS::getFile (const Pathname & filename, const ByteCount &expectedFileSize_r) const
214  {
215  MediaHandler::getFile( filename, expectedFileSize_r );
216  }
217 
219  //
220  // METHOD NAME : MediaNFS::getDir
221  // METHOD TYPE : PMError
222  //
223  // DESCRIPTION : Asserted that media is attached.
224  //
225  void MediaNFS::getDir( const Pathname & dirname, bool recurse_r ) const
226  {
227  MediaHandler::getDir( dirname, recurse_r );
228  }
229 
231  //
232  //
233  // METHOD NAME : MediaNFS::getDirInfo
234  // METHOD TYPE : PMError
235  //
236  // DESCRIPTION : Asserted that media is attached and retlist is empty.
237  //
238  void MediaNFS::getDirInfo( std::list<std::string> & retlist,
239  const Pathname & dirname, bool dots ) const
240  {
241  MediaHandler::getDirInfo( retlist, dirname, dots );
242  }
243 
245  //
246  //
247  // METHOD NAME : MediaNFS::getDirInfo
248  // METHOD TYPE : PMError
249  //
250  // DESCRIPTION : Asserted that media is attached and retlist is empty.
251  //
253  const Pathname & dirname, bool dots ) const
254  {
255  MediaHandler::getDirInfo( retlist, dirname, dots );
256  }
257 
258  bool MediaNFS::getDoesFileExist( const Pathname & filename ) const
259  {
260  return MediaHandler::getDoesFileExist( filename );
261  }
262 
263 
264  } // namespace media
265 } // namespace zypp
std::string asString(const Patch::Category &obj)
Definition: Patch.cc:117
#define MIL
Definition: Logger.h:64
virtual bool isAttached() const
True if media is attached.
Definition: MediaNFS.cc:187
Interface to the mount program.
Definition: Mount.h:69
virtual void getFile(const Pathname &filename, const ByteCount &expectedFileSize_r) const
Call concrete handler to provide file below attach point.
Definition: MediaNFS.cc:213
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:321
virtual void getDir(const Pathname &dirname, bool recurse_r) const =0
Call concrete handler to provide directory content (not recursive!) below attach point.
std::string join(TIterator begin, TIterator end, const C_Str &sep_r=" ")
Join strings using separator sep_r (defaults to BLANK).
Definition: String.h:758
Store and operate with byte count.
Definition: ByteCount.h:30
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
Definition: Url.cc:598
virtual bool getDoesFileExist(const Pathname &filename) const
check if a file exists
Definition: MediaNFS.cc:258
std::string getHost(EEncoding eflag=zypp::url::E_DECODED) const
Returns the hostname or IP from the URL authority.
Definition: Url.cc:582
zypp::RW_pointer< MediaSource > MediaSourceRef
Definition: MediaSource.h:124
virtual void attachTo(bool next=false)
Call concrete handler to attach the media.
Definition: MediaNFS.cc:59
virtual void getFile(const Pathname &filename, const ByteCount &expectedFileSize_r) const
Call concrete handler to provide file below attach point.
void setAttachPoint(const Pathname &path, bool temp)
Set a new attach point.
Pathname createAttachPoint() const
Try to create a default / temporary attach point.
virtual void releaseFrom(const std::string &ejectDev)
Call concrete handler to release the media.
Definition: MediaNFS.cc:200
virtual void getDirInfo(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const
Call concrete handler to provide a content list of directory on media via retlist.
Definition: MediaNFS.cc:238
void mount(const std::string &source, const std::string &target, const std::string &filesystem, const std::string &options, const Environment &environment=Environment())
mount device
Definition: Mount.cc:66
AttachPointRef attachPoint
Definition: MediaSource.h:145
AttachedMedia findAttachedMedia(const MediaSourceRef &media) const
Ask the media manager if specified media source is already attached.
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t")
Split line_r into words.
Definition: String.h:518
MediaSourceRef mediaSource
Definition: MediaSource.h:144
Abstract base class for 'physical' MediaHandler like MediaCD, etc.
Definition: MediaHandler.h:45
A simple structure containing references to a media source and its attach point.
Definition: MediaSource.h:133
const Url _url
Url to handle.
Definition: MediaHandler.h:110
void setMediaSource(const MediaSourceRef &ref)
Set new media source reference.
Just inherits Exception to separate media exceptions.
std::list< DirEntry > DirContent
Returned by readdir.
Definition: PathInfo.h:547
std::string getQueryParam(const std::string &param, EEncoding eflag=zypp::url::E_DECODED) const
Return the value for the specified query parameter.
Definition: Url.cc:654
bool isUseableAttachPoint(const Pathname &path, bool mtab=true) const
Ask media manager, if the specified path is already used as attach point or if there are another atta...
void removeAttachPoint()
Remove unused attach point.
Media source internally used by MediaManager and MediaHandler.
Definition: MediaSource.h:36
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:325
virtual void getDirInfo(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const =0
Call concrete handler to provide a content list of directory on media via retlist.
virtual bool getDoesFileExist(const Pathname &filename) const =0
check if a file exists
Pathname attachPoint() const
Return the currently used attach point.
#define NFS_MOUNT_TIMEOUT
Value of NFS mount minor timeout (passed to timeo option of the NFS mount) in tenths of a second...
Definition: MediaNFS.h:24
bool checkAttached(bool matchMountFs) const
Check actual mediaSource attachment against the current mount table of the system.
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:527
Url url() const
Url used.
Definition: MediaHandler.h:506
Url manipulation class.
Definition: Url.h:87
void umount(const std::string &path)
umount device
Definition: Mount.cc:162
virtual void getDir(const Pathname &dirname, bool recurse_r) const
Call concrete handler to provide directory content (not recursive!) below attach point.
Definition: MediaNFS.cc:225
#define DBG
Definition: Logger.h:63