libzypp  17.31.31
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 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 
53  _isofile = _url.getQueryParam("iso");
54  if( _isofile.empty())
55  {
56  ERR << "Media url does not contain iso filename" << std::endl;
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() );
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;
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;
88  }
89  if( src.getScheme() == "iso")
90  {
91  ERR << "ISO filename source media url with iso scheme (nested iso): "
92  << src.asString() << std::endl;
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;
107  }
108 
109  MediaManager manager;
110 
111  _parentId = manager.open(src, _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",
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;
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:533
std::string asString(const Patch::Category &obj)
Definition: Patch.cc:122
virtual 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:96
Interface to the mount program.
Definition: mount.h:74
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:428
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.
zypp::RW_pointer< MediaSource > MediaSourceRef
Definition: MediaSource.h:124
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...
Base class for all URL exceptions.
Definition: UrlException.h:31
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
std::string basename() const
Return the last component of this path.
Definition: Pathname.h:128
virtual void attachTo(bool next=false) override
Call concrete handler to attach the media.
Definition: MediaISO.cc:142
bool checkAttached(bool matchMountFs) const
Check actual mediaSource attachment against the current mount table of the system.
#define ERR
Definition: Logger.h:98
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:105
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:114
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
Definition: Url.cc:764
AttachPointRef attachPoint
Definition: MediaSource.h:145
std::string asString() const
Returns a default string representation of the Url object.
Definition: Url.cc:497
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:660
MediaSourceRef mediaSource
Definition: MediaSource.h:144
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:133
const Url _url
Url to handle.
Definition: MediaHandler.h:113
void setMediaSource(const MediaSourceRef &ref)
Set new media source reference.
const std::string & asString() const
String representation.
Definition: Pathname.h:91
Just inherits Exception to separate media exceptions.
virtual bool isAttached() const override
True if media is attached.
Definition: MediaISO.cc:136
Pathname dirname() const
Return all but the last component od this path.
Definition: Pathname.h:124
#define WAR
Definition: Logger.h:97
std::list< DirEntry > DirContent
Returned by readdir.
Definition: PathInfo.h:518
bool isValid() const
Verifies the Url.
Definition: Url.cc:489
void removeAttachPoint()
Remove unused attach point.
virtual 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).
virtual 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:36
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:436
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:145
Pathname attachPoint() const
Return the currently used attach point.
MediaAccessId _parentId
Access Id of media handler we depend on.
Definition: MediaHandler.h:118
virtual bool getDoesFileExist(const Pathname &filename) const override
check if a file exists
Definition: MediaISO.cc:297
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:220
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:945
virtual 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: CodePitfalls.doc:1
void release(const std::string &ejectDev="")
Use concrete handler to release the media.
MediaAccessId open(const Url &url, const Pathname &preferred_attach_point="")
Opens the media access for specified with the url.
virtual void getFile(const OnMediaLocation &file) const
Call concrete handler to provide file below attach point.
virtual ~MediaISO() override
Definition: MediaISO.cc:115
Url manipulation class.
Definition: Url.h:91
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:95
MediaISO(const Url &url_r, const Pathname &attach_point_hint_r)
Definition: MediaISO.cc:44