libzypp  11.13.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 
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
214  {
215  MediaHandler::getFile( filename );;
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