libzypp  17.37.5
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 
19 using std::endl;
20 
22 namespace 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 MediaUrl &url_r,
45  const Pathname &attach_point_hint_r)
46  : MediaHandler(url_r, {}, attach_point_hint_r,
47  url_r.url().getPathName(), // urlpath below attachpoint
48  false) // does_download
49  {
50  MIL << "MediaISO::MediaISO(" << url_r.url() << ", "
51  << attach_point_hint_r << ")" << std::endl;
52 
53  _isofile = _url.url().getQueryParam("iso");
54  if( _isofile.empty())
55  {
56  ERR << "Media url does not contain iso filename" << std::endl;
58  }
59 
60  _filesystem = _url.url().getQueryParam("filesystem");
61  if( _filesystem.empty())
62  _filesystem = "auto";
63 
64  Url src;
65  {
66  const std::string & arg { _url.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.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({MediaUrl(src)}, _url.url().getQueryParam("mnt"));
112  }
113 
114  // ---------------------------------------------------------------
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
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  {
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.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;
197  return;
198  }
199 
201  {
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  {
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  // ---------------------------------------------------------------
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 
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:551
std::string asString(const Patch::Category &obj)
Definition: Patch.cc:122
void getDir(const Pathname &dirname, bool recurse_r) const override
Call concrete handler to provide directory content (not recursive!) below attach point.
Definition: MediaISO.cc:275
#define MIL
Definition: Logger.h:100
Interface to the mount program.
Definition: mount.h:75
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:459
Describes a resource file located on a medium.
virtual void getDir(const Pathname &dirname, bool recurse_r) const =0
Call concrete handler to provide directory content (not recursive!) below attach point.
const MediaUrl _url
Primary Url.
Definition: MediaHandler.h:118
void setAttachPoint(const Pathname &path, bool temp)
Set a new attach point.
std::string _filesystem
Definition: MediaISO.h:39
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...
bool isOpen(MediaAccessId accessId) const
Query if the media access is open / exists.
ZYPP_DEPRECATED void provideFile(MediaAccessId accessId, const Pathname &filename, const ByteCount &expectedFileSize) const
void attachTo(bool next=false) override
Call concrete handler to attach the media.
Definition: MediaISO.cc:142
std::list< DirEntry > DirContent
Returned by readdir.
Definition: PathInfo.h:526
bool checkAttached(bool matchMountFs) const
Check actual mediaSource attachment against the current mount table of the system.
#define ERR
Definition: Logger.h:102
zypp::Url _url
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
Pathname localPath(MediaAccessId accessId, const Pathname &pathname) const
Shortcut for &#39;localRoot() + pathname&#39;, but returns an empty pathname if media is not attached...
void remember(const Exception &old_r)
Store an other Exception as history.
Definition: Exception.cc:154
void release(MediaAccessId accessId, const std::string &ejectDev="")
Release the attached media and optionally eject.
bool empty() const
Test for an empty path.
Definition: Pathname.h:116
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
Definition: Url.cc:782
AttachPointRef attachPoint
Definition: MediaSource.h:146
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
MediaSourceRef mediaSource
Definition: MediaSource.h:145
Abstract base class for &#39;physical&#39; MediaHandler like MediaCD, etc.
Definition: MediaHandler.h:51
A simple structure containing references to a media source and its attach point.
Definition: MediaSource.h:134
void setMediaSource(const MediaSourceRef &ref)
Set new media source reference.
const std::string & asString() const
String representation.
Definition: Pathname.h:93
Just inherits Exception to separate media exceptions.
bool isAttached() const override
True if media is attached.
Definition: MediaISO.cc:136
#define WAR
Definition: Logger.h:101
MediaISO(const MediaUrl &url_r, const Pathname &attach_point_hint_r)
Definition: MediaISO.cc:44
Pathname expandlink(const Pathname &path_r)
Recursively follows the symlink pointed to by path_r and returns the Pathname to the real file or dir...
Definition: PathInfo.cc:950
bool isValid() const
Verifies the Url.
Definition: Url.cc:507
void removeAttachPoint()
Remove unused attach point.
void getDirInfo(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const override
Call concrete handler to provide a content list of directory on media via retlist.
Definition: MediaISO.cc:282
void attach(MediaAccessId accessId)
Attach the media using the concrete handler (checks all devices).
void getFile(const OnMediaLocation &file) const override
Call concrete handler to provide file below attach point.
Definition: MediaISO.cc:269
Media source internally used by MediaManager and MediaHandler.
Definition: MediaSource.h:37
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:475
Manages access to the &#39;physical&#39; media, e.g CDROM drives, Disk volumes, directory trees...
Definition: MediaManager.h:453
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
AttachedMedia findAttachedMedia(const MediaSourceRef &media) const
Ask the media manager if specified media source is already attached.
Base class for Exception.
Definition: Exception.h:152
Pathname attachPoint() const
Return the currently used attach point.
MediaAccessId _parentId
Access Id of media handler we depend on.
Definition: MediaHandler.h:123
bool getDoesFileExist(const Pathname &filename) const override
check if a file exists
Definition: MediaISO.cc:297
zypp::RW_pointer< MediaSource > MediaSourceRef
Definition: MediaSource.h:125
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:225
void releaseFrom(const std::string &ejectDev="") override
Call concrete handler to release the media.
Definition: MediaISO.cc:243
Pathname createAttachPoint() const
Try to create a default / temporary attach point.
Easy-to use interface to the ZYPP dependency resolver.
Definition: Application.cc:19
void release(const std::string &ejectDev="")
Use concrete handler to release the media.
virtual void getFile(const OnMediaLocation &file) const
Call concrete handler to provide file below attach point.
~MediaISO() override
Definition: MediaISO.cc:115
Url manipulation class.
Definition: Url.h:92
void umount(const std::string &path)
umount device
Definition: mount.cc:117
void close(MediaAccessId accessId)
Close the media access with specified id.
#define DBG
Definition: Logger.h:99