- Lowered isAttached retry limit (wait for mtab update)
[platform/upstream/libzypp.git] / zypp / media / MediaNFS.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaNFS.cc
10  *
11 */
12
13 #include <iostream>
14
15 #include "zypp/base/Logger.h"
16 #include "zypp/base/String.h"
17 #include "zypp/media/MediaNFS.h"
18 #include "zypp/media/Mount.h"
19
20 #include <dirent.h>
21
22 using namespace std;
23
24 namespace zypp {
25   namespace media {
26
27     ///////////////////////////////////////////////////////////////////
28     //
29     //  CLASS NAME : MediaNFS
30     //
31     ///////////////////////////////////////////////////////////////////
32     
33     ///////////////////////////////////////////////////////////////////
34     //
35     //
36     //  METHOD NAME : MediaNFS::MediaNFS
37     //  METHOD TYPE : Constructor
38     //
39     //  DESCRIPTION :
40     //
41     MediaNFS::MediaNFS( const Url &      url_r,
42                         const Pathname & attach_point_hint_r )
43       : MediaHandler( url_r, attach_point_hint_r,
44                       "/", // urlpath at attachpoint
45                       false ) // does_download
46     {
47         MIL << "MediaNFS::MediaNFS(" << url_r << ", " << attach_point_hint_r << ")" << endl;
48     }
49
50     ///////////////////////////////////////////////////////////////////
51     //
52     //
53     //  METHOD NAME : MediaNFS::attachTo
54     //  METHOD TYPE : PMError
55     //
56     //  DESCRIPTION : Asserted that not already attached, and attachPoint is a directory.
57     //
58     void MediaNFS::attachTo(bool next)
59     {
60       if(_url.getHost().empty())
61         ZYPP_THROW(MediaBadUrlEmptyHostException(_url));
62       if(next)
63         ZYPP_THROW(MediaNotSupportedException(_url));
64
65       string path = _url.getHost();
66       path += ':';
67       path += Pathname(_url.getPathName()).asString();
68
69       MediaSourceRef media( new MediaSource("nfs", path));
70       AttachedMedia  ret( findAttachedMedia( media));
71
72       if( ret.mediaSource &&
73           ret.attachPoint &&
74           !ret.attachPoint->empty())
75       {
76         DBG << "Using a shared media "
77             << ret.mediaSource->name
78             << " attached on "
79             << ret.attachPoint->path
80             << endl;
81
82         removeAttachPoint();
83         setAttachPoint(ret.attachPoint);
84         setMediaSource(ret.mediaSource);
85         return;
86       }
87
88       const char* const filesystem = "nfs";
89       std::string       mountpoint = attachPoint().asString();
90       Mount mount;
91
92       if( !isUseableAttachPoint(attachPoint()))
93       {
94         mountpoint = createAttachPoint().asString();
95         if( mountpoint.empty())
96           ZYPP_THROW( MediaBadAttachPointException(url()));
97         setAttachPoint( mountpoint, true);
98       }
99
100       string options = _url.getQueryParam("mountoptions");
101       if(options.empty())
102       {
103         options="ro";
104       }
105     
106       // Add option "nolock", unless option "lock" or "unlock" is already set.
107       // This should prevent the mount command hanging when the portmapper isn't
108       // running.
109       vector<string> optionList;
110       str::split( options, std::back_inserter(optionList), "," );
111       vector<string>::const_iterator it;
112       for( it = optionList.begin(); it != optionList.end(); ++it ) {
113         if ( *it == "lock" || *it == "nolock" ) break;
114       }
115       if ( it == optionList.end() ) {
116         optionList.push_back( "nolock" );
117         options = str::join( optionList, "," );
118       }
119
120       mount.mount(path,mountpoint,filesystem,options);
121
122       setMediaSource(media);
123
124       // wait for /etc/mtab update ...
125       // (shouldn't be needed)
126       int limit = 3;
127       bool mountsucceeded;
128       while( !(mountsucceeded=isAttached()) && --limit)
129       {
130         sleep(1);
131       }
132
133       if( !mountsucceeded)
134       {
135         setMediaSource(MediaSourceRef());
136         try
137         {
138           mount.umount(attachPoint().asString());
139         }
140         catch (const MediaException & excpt_r)
141         {
142           ZYPP_CAUGHT(excpt_r);
143         }
144         ZYPP_THROW(MediaMountException(
145           "Unable to verify that the media was mounted",
146           path, mountpoint
147         ));
148       }
149     }
150
151     ///////////////////////////////////////////////////////////////////
152     //
153     //  METHOD NAME : MediaNFS::isAttached
154     //  METHOD TYPE : bool
155     //
156     //  DESCRIPTION : Override check if media is attached.
157     //
158     bool
159     MediaNFS::isAttached() const
160     {
161       return checkAttached(false, true);
162     }
163
164     ///////////////////////////////////////////////////////////////////
165     //
166     //
167     //  METHOD NAME : MediaNFS::releaseFrom
168     //  METHOD TYPE : PMError
169     //
170     //  DESCRIPTION : Asserted that media is attached.
171     //
172     void MediaNFS::releaseFrom( bool eject )
173     {
174       Mount mount;
175       mount.umount(attachPoint().asString());
176     }
177
178
179     ///////////////////////////////////////////////////////////////////
180     //
181     //  METHOD NAME : MediaNFS::getFile
182     //  METHOD TYPE : PMError
183     //
184     //  DESCRIPTION : Asserted that media is attached.
185     //
186     void MediaNFS::getFile (const Pathname & filename) const
187     {
188       MediaHandler::getFile( filename );;
189     }
190     
191     ///////////////////////////////////////////////////////////////////
192     //
193     //  METHOD NAME : MediaNFS::getDir
194     //  METHOD TYPE : PMError
195     //
196     //  DESCRIPTION : Asserted that media is attached.
197     //
198     void MediaNFS::getDir( const Pathname & dirname, bool recurse_r ) const
199     {
200       MediaHandler::getDir( dirname, recurse_r );
201     }
202     
203     ///////////////////////////////////////////////////////////////////
204     //
205     //
206     //  METHOD NAME : MediaNFS::getDirInfo
207     //  METHOD TYPE : PMError
208     //
209     //  DESCRIPTION : Asserted that media is attached and retlist is empty.
210     //
211     void MediaNFS::getDirInfo( std::list<std::string> & retlist,
212                               const Pathname & dirname, bool dots ) const
213     {
214       MediaHandler::getDirInfo( retlist, dirname, dots );
215     }
216     
217     ///////////////////////////////////////////////////////////////////
218     //
219     //
220     //  METHOD NAME : MediaNFS::getDirInfo
221     //  METHOD TYPE : PMError
222     //
223     //  DESCRIPTION : Asserted that media is attached and retlist is empty.
224     //
225     void MediaNFS::getDirInfo( filesystem::DirContent & retlist,
226                            const Pathname & dirname, bool dots ) const
227     {
228       MediaHandler::getDirInfo( retlist, dirname, dots );
229     }
230
231   } // namespace media
232 } // namespace zypp