libzypp 17.35.15
MediaISO.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12#include <iostream>
13
14#include <zypp/base/Logger.h>
15#include <zypp-media/Mount>
16
17#include <zypp/media/MediaISO.h>
18
19using std::endl;
20
22namespace zypp
23{
24
26 namespace media
27 {
28
30 //
31 // MediaISO Url:
32 //
33 // Schema: iso
34 // Path name: subdir to the location of desired files inside
35 // of the ISO.
36 // Query parameters:
37 // url: The iso filename source media url pointing
38 // to a directory containing the ISO file.
39 // mnt: Prefered attach point for source media url.
40 // iso: The name of the iso file.
41 // filesystem: Optional, defaults to "auto".
42 //
44 MediaISO::MediaISO(const Url &url_r,
45 const Pathname &attach_point_hint_r)
46 : MediaHandler(url_r, attach_point_hint_r,
47 url_r.getPathName(), // urlpath below attachpoint
48 false) // does_download
49 {
50 MIL << "MediaISO::MediaISO(" << url_r << ", "
51 << attach_point_hint_r << ")" << std::endl;
52
54 if( _isofile.empty())
55 {
56 ERR << "Media url does not contain iso filename" << std::endl;
57 ZYPP_THROW(MediaBadUrlEmptyDestinationException(_url));
58 }
59
60 _filesystem = _url.getQueryParam("filesystem");
61 if( _filesystem.empty())
62 _filesystem = "auto";
63
64 Url src;
65 {
66 const std::string & arg { _url.getQueryParam("url") };
67 if ( arg.empty() ) {
68 src = "dir:/";
69 src.setPathName( _isofile.dirname() );
70 _isofile = _isofile.basename();
71 }
72 else try {
73 src = arg;
74 }
75 catch( const url::UrlException & e )
76 {
77 ZYPP_CAUGHT(e);
78 ERR << "Unable to parse iso filename source media url" << std::endl;
79 MediaBadUrlException ne(_url);
80 ne.remember(e);
81 ZYPP_THROW(ne);
82 }
83 }
84 if( !src.isValid())
85 {
86 ERR << "Invalid iso filename source media url" << std::endl;
87 ZYPP_THROW(MediaBadUrlException(src));
88 }
89 if( src.getScheme() == "iso")
90 {
91 ERR << "ISO filename source media url with iso scheme (nested iso): "
92 << src.asString() << std::endl;
93 ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
94 }
95 else
96 if( !(src.getScheme() == "hd" ||
97 src.getScheme() == "dir" ||
98 src.getScheme() == "file" ||
99 src.getScheme() == "nfs" ||
100 src.getScheme() == "nfs4" ||
101 src.getScheme() == "smb" ||
102 src.getScheme() == "cifs"))
103 {
104 ERR << "ISO filename source media url scheme is not supported: "
105 << src.asString() << std::endl;
106 ZYPP_THROW(MediaUnsupportedUrlSchemeException(src));
107 }
108
109 MediaManager manager;
110
111 _parentId = manager.open(src, _url.getQueryParam("mnt"));
112 }
113
114 // ---------------------------------------------------------------
115 MediaISO::~MediaISO()
116 {
117 try
118 {
119 release();
120
121 if( _parentId)
122 {
123 DBG << "Closing parent handler..." << std::endl;
124 MediaManager manager;
125 if(manager.isOpen(_parentId))
126 manager.close(_parentId);
127 _parentId = 0;
128 }
129 }
130 catch( ... )
131 {}
132 }
133
134 // ---------------------------------------------------------------
135 bool
136 MediaISO::isAttached() const
137 {
138 return checkAttached(false);
139 }
140
141 // ---------------------------------------------------------------
142 void MediaISO::attachTo(bool next)
143 {
144 if(next)
146
147 MediaManager manager;
148 manager.attach(_parentId);
149
150 try
151 {
152 manager.provideFile(_parentId, OnMediaLocation(_isofile) );
153 }
154 catch(const MediaException &e1)
155 {
156 ZYPP_CAUGHT(e1);
157 try
158 {
159 manager.release(_parentId);
160 }
161 catch(const MediaException &e2)
162 {
163 ZYPP_CAUGHT(e2);
164 }
165
167 "Unable to find iso filename on source media",
168 _url.asString(), attachPoint().asString()
169 );
170 e3.remember(e1);
171 ZYPP_THROW(e3);
172 }
173
174 // if the provided file is a symlink, expand it (#274651)
175 // (this will probably work only for file/dir and cd/dvd schemes)
176 Pathname isofile = expandlink(manager.localPath(_parentId, _isofile));
177 if( isofile.empty() || !PathInfo(isofile).isFile())
178 {
180 }
181
182 MediaSourceRef media( new MediaSource("iso", isofile.asString() ) );
183
184 AttachedMedia ret( findAttachedMedia(media));
185 if( ret.mediaSource &&
186 ret.attachPoint &&
187 !ret.attachPoint->empty())
188 {
189 DBG << "Using a shared media "
190 << ret.mediaSource->name
191 << " attached on "
192 << ret.attachPoint->path
193 << std::endl;
194 removeAttachPoint();
195 setAttachPoint(ret.attachPoint);
196 setMediaSource(ret.mediaSource);
197 return;
198 }
199
200 if( !isUseableAttachPoint( attachPoint() ) )
201 {
202 setAttachPoint( createAttachPoint(), true );
203 }
204 std::string mountpoint( attachPoint().asString() );
205 std::string mountopts("ro,loop");
206
207 Mount mount;
208 mount.mount(isofile.asString(), mountpoint,
209 _filesystem, mountopts);
210
211 setMediaSource(media);
212
213 // wait for /etc/mtab update ...
214 // (shouldn't be needed)
215 int limit = 3;
216 bool mountsucceeded = false;
217 while( !(mountsucceeded=isAttached()) && --limit)
218 {
219 sleep(1);
220 }
221
222 if( !mountsucceeded)
223 {
224 setMediaSource(MediaSourceRef());
225 try
226 {
227 mount.umount(attachPoint().asString());
228 manager.release(_parentId);
229 }
230 catch (const MediaException & excpt_r)
231 {
232 ZYPP_CAUGHT(excpt_r);
233 }
235 "Unable to verify that the media was mounted",
236 isofile.asString(), mountpoint
237 ));
238 }
239 }
240
241 // ---------------------------------------------------------------
242
243 void MediaISO::releaseFrom(const std::string & ejectDev)
244 {
245 Mount mount;
246 mount.umount(attachPoint().asString());
247
248 if( _parentId)
249 {
250 // Unmounting the iso already succeeded,
251 // so don't let exceptions escape.
252 MediaManager manager;
253 try
254 {
255 manager.release(_parentId);
256 }
257 catch ( const Exception & excpt_r )
258 {
259 ZYPP_CAUGHT( excpt_r );
260 WAR << "Not been able to cleanup the parent mount." << endl;
261 }
262 }
263 // else:
264 // the media manager has reset the _parentId
265 // and will destroy the parent handler itself.
266 }
267
268 // ---------------------------------------------------------------
269 void MediaISO::getFile( const OnMediaLocation &file ) const
270 {
271 MediaHandler::getFile(file);
272 }
273
274 // ---------------------------------------------------------------
275 void MediaISO::getDir(const Pathname &dirname,
276 bool recurse_r) const
277 {
278 MediaHandler::getDir(dirname, recurse_r);
279 }
280
281 // ---------------------------------------------------------------
282 void MediaISO::getDirInfo(std::list<std::string> &retlist,
283 const Pathname &dirname,
284 bool dots) const
285 {
286 MediaHandler::getDirInfo( retlist, dirname, dots );
287 }
288
289 // ---------------------------------------------------------------
290 void MediaISO::getDirInfo(filesystem::DirContent &retlist,
291 const Pathname &dirname,
292 bool dots) const
293 {
294 MediaHandler::getDirInfo(retlist, dirname, dots);
295 }
296
297 bool MediaISO::getDoesFileExist( const Pathname & filename ) const
298 {
299 return MediaHandler::getDoesFileExist( filename );
300 }
301
303 } // namespace media
305
307} // namespace zypp
309
310// vim: set ts=2 sts=2 sw=2 ai et:
311
Base class for Exception.
Definition Exception.h:147
void remember(const Exception &old_r)
Store an other Exception as history.
Definition Exception.cc:141
Describes a resource file located on a medium.
Url manipulation class.
Definition Url.h:92
std::string asString() const
Returns a default string representation of the Url object.
Definition Url.cc:515
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:678
Wrapper class for stat/lstat.
Definition PathInfo.h:222
const std::string & asString() const
String representation.
Definition Pathname.h:93
bool empty() const
Test for an empty path.
Definition Pathname.h:116
Just inherits Exception to separate media exceptions.
Abstract base class for 'physical' MediaHandler like MediaCD, etc.
const Url _url
Url to handle.
MediaISO(const Url &url_r, const Pathname &attach_point_hint_r)
Definition MediaISO.cc:44
std::string _filesystem
Definition MediaISO.h:39
Manages access to the 'physical' media, e.g CDROM drives, Disk volumes, directory trees,...
MediaAccessId open(const Url &url, const Pathname &preferred_attach_point="")
Opens the media access for specified with the url.
void attach(MediaAccessId accessId)
Attach the media using the concrete handler (checks all devices).
bool isOpen(MediaAccessId accessId) const
Query if the media access is open / exists.
void close(MediaAccessId accessId)
Close the media access with specified id.
ZYPP_DEPRECATED void provideFile(MediaAccessId accessId, const Pathname &filename, const ByteCount &expectedFileSize) const
void release(MediaAccessId accessId, const std::string &ejectDev="")
Release the attached media and optionally eject.
Pathname localPath(MediaAccessId accessId, const Pathname &pathname) const
Shortcut for 'localRoot() + pathname', but returns an empty pathname if media is not attached.
Media source internally used by MediaManager and MediaHandler.
Definition MediaSource.h:38
Interface to the mount program.
Definition mount.h:76
void umount(const std::string &path)
umount device
Definition mount.cc:117
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:62
Base class for all URL exceptions.
std::list< DirEntry > DirContent
Returned by readdir.
Definition PathInfo.h:519
Easy-to use interface to the ZYPP dependency resolver.
std::string asString(const Patch::Category &obj)
Definition Patch.cc:122
zypp::Url _url
A simple structure containing references to a media source and its attach point.
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:440
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:424
#define DBG
Definition Logger.h:99
#define MIL
Definition Logger.h:100
#define WAR
Definition Logger.h:101