libzypp  16.22.5
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 
90  {
92  }
93  std::string mountpoint( attachPoint().asString() );
94 
95  std::string filesystem( _url.getScheme() );
96  if ( filesystem != "nfs4" && _url.getQueryParam("type") == "nfs4" )
97  {
98  filesystem = "nfs4";
99  }
100 
101  string options = _url.getQueryParam("mountoptions");
102  if(options.empty())
103  {
104  options="ro";
105  }
106 
107  vector<string> optionList;
108  str::split( options, std::back_inserter(optionList), "," );
109  vector<string>::const_iterator it;
110  bool contains_lock = false, contains_soft = false,
111  contains_timeo = false, contains_hard = false;
112 
113  for( it = optionList.begin(); it != optionList.end(); ++it ) {
114  if ( *it == "lock" || *it == "nolock" ) contains_lock = true;
115  else if ( *it == "soft") contains_soft = true;
116  else if ( *it == "hard") contains_hard = true;
117  else if ( it->find("timeo") != string::npos ) contains_timeo = true;
118  }
119 
120  if ( !(contains_lock && contains_soft) ) {
121  // Add option "nolock", unless option "lock" or "unlock" is already set.
122  // This should prevent the mount command hanging when the portmapper isn't
123  // running.
124  if ( !contains_lock ) {
125  optionList.push_back( "nolock" );
126  }
127  // Add options "soft,timeo=NFS_MOUNT_TIMEOUT", unless they are set
128  // already or "hard" option is explicitly specified. This prevent
129  // the mount command from hanging when the nfs server is not responding
130  // and file transactions from an unresponsive to throw an error after
131  // a short time instead of hanging forever
132  if ( !(contains_soft || contains_hard) ) {
133  optionList.push_back( "soft" );
134  if ( !contains_timeo ) {
135  ostringstream s;
136  s << "timeo=" << NFS_MOUNT_TIMEOUT;
137  optionList.push_back( s.str() );
138  }
139  }
140  options = str::join( optionList, "," );
141  }
142 
143  Mount mount;
144  mount.mount(path,mountpoint,filesystem,options);
145 
146  setMediaSource(media);
147 
148  // wait for /etc/mtab update ...
149  // (shouldn't be needed)
150  int limit = 3;
151  bool mountsucceeded;
152  while( !(mountsucceeded=isAttached()) && --limit)
153  {
154  sleep(1);
155  }
156 
157  if( !mountsucceeded)
158  {
160  try
161  {
162  mount.umount(attachPoint().asString());
163  }
164  catch (const MediaException & excpt_r)
165  {
166  ZYPP_CAUGHT(excpt_r);
167  }
169  "Unable to verify that the media was mounted",
170  path, mountpoint
171  ));
172  }
173  }
174 
176  //
177  // METHOD NAME : MediaNFS::isAttached
178  // METHOD TYPE : bool
179  //
180  // DESCRIPTION : Override check if media is attached.
181  //
182  bool
184  {
185  return checkAttached(true);
186  }
187 
189  //
190  //
191  // METHOD NAME : MediaNFS::releaseFrom
192  // METHOD TYPE : void
193  //
194  // DESCRIPTION : Asserted that media is attached.
195  //
196  void MediaNFS::releaseFrom( const std::string & ejectDev )
197  {
198  Mount mount;
199  mount.umount(attachPoint().asString());
200  }
201 
203  //
204  // METHOD NAME : MediaNFS::getFile
205  // METHOD TYPE : PMError
206  //
207  // DESCRIPTION : Asserted that media is attached.
208  //
209  void MediaNFS::getFile (const Pathname & filename, const ByteCount &expectedFileSize_r) const
210  {
211  MediaHandler::getFile( filename, expectedFileSize_r );
212  }
213 
215  //
216  // METHOD NAME : MediaNFS::getDir
217  // METHOD TYPE : PMError
218  //
219  // DESCRIPTION : Asserted that media is attached.
220  //
221  void MediaNFS::getDir( const Pathname & dirname, bool recurse_r ) const
222  {
223  MediaHandler::getDir( dirname, recurse_r );
224  }
225 
227  //
228  //
229  // METHOD NAME : MediaNFS::getDirInfo
230  // METHOD TYPE : PMError
231  //
232  // DESCRIPTION : Asserted that media is attached and retlist is empty.
233  //
234  void MediaNFS::getDirInfo( std::list<std::string> & retlist,
235  const Pathname & dirname, bool dots ) const
236  {
237  MediaHandler::getDirInfo( retlist, dirname, dots );
238  }
239 
241  //
242  //
243  // METHOD NAME : MediaNFS::getDirInfo
244  // METHOD TYPE : PMError
245  //
246  // DESCRIPTION : Asserted that media is attached and retlist is empty.
247  //
249  const Pathname & dirname, bool dots ) const
250  {
251  MediaHandler::getDirInfo( retlist, dirname, dots );
252  }
253 
254  bool MediaNFS::getDoesFileExist( const Pathname & filename ) const
255  {
256  return MediaHandler::getDoesFileExist( filename );
257  }
258 
259 
260  } // namespace media
261 } // namespace zypp
#define MIL
Definition: Logger.h:64
virtual bool isAttached() const
True if media is attached.
Definition: MediaNFS.cc:183
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:209
std::string asString(const DefaultIntegral< Tp, TInitial > &obj)
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:350
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:759
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:254
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:196
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:234
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:519
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:354
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 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:221
#define DBG
Definition: Logger.h:63