libzypp 17.36.1
MediaDISK.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
13#include <zypp/base/Logger.h>
14#include <zypp/base/String.h>
15#include <zypp-media/Mount>
18
19#include <iostream>
20#include <fstream>
21#include <sstream>
22
23#include <sys/types.h>
24#include <sys/mount.h>
25#include <errno.h>
26#include <dirent.h>
27
28using std::endl;
29
30/*
31** verify devices names as late as possible (while attach)
32*/
33#define DELAYED_VERIFY 1
34
35
36namespace zypp {
37 namespace media {
38
40 //
41 // CLASS NAME : MediaDISK
42 //
44
46 //
47 //
48 // METHOD NAME : MediaDISK::MediaDISK
49 // METHOD TYPE : Constructor
50 //
51 // DESCRIPTION :
52 //
56 url_r.getPathName(), // urlpath below attachpoint
57 false ) // does_download
58 {
59 MIL << "MediaDISK::MediaDISK(" << url_r << ", " << attach_point_hint_r << ")" << endl;
60
62 if( _device.empty())
63 {
64 ERR << "Media url does not contain a device specification" << std::endl;
66 }
67#if DELAYED_VERIFY
68 DBG << "Verify of " << _device << " delayed" << std::endl;
69#else
71 {
73 }
74#endif
75
76 _filesystem = _url.getQueryParam("filesystem");
77 if(_filesystem.empty())
78 _filesystem="auto";
79
80 }
81
83 //
84 // METHOD NAME : MediaDISK::verifyIfDiskVolume
85 // METHOD TYPE : void
86 //
87 // DESCRIPTION : Check if specified device file name is
88 // a disk volume device or throw an error.
89 //
91 {
92 if( dev_name.empty() ||
93 dev_name.asString().compare(0, sizeof("/dev/")-1, "/dev/"))
94 {
95 ERR << "Specified device name " << dev_name
96 << " is not allowed" << std::endl;
97 return false;
98 }
99
101 if( !dev_info.isBlk())
102 {
103 ERR << "Specified device name " << dev_name
104 << " is not a block device" << std::endl;
105 return false;
106 }
107
108 // check if a volume using /dev/disk/by-uuid links first
109 {
110 Pathname dpath("/dev/disk/by-uuid");
111 std::list<Pathname> dlist;
113 {
114 std::list<Pathname>::const_iterator it;
115 for(it = dlist.begin(); it != dlist.end(); ++it)
116 {
118 if( vol_info.isBlk() && vol_info.devMajor() == dev_info.devMajor() &&
119 vol_info.devMinor() == dev_info.devMinor())
120 {
121 DBG << "Specified device name " << dev_name
122 << " is a volume (disk/by-uuid link "
123 << vol_info.path() << ")"
124 << std::endl;
125 return true;
126 }
127 }
128 }
129 }
130
131 // check if a volume using /dev/disk/by-label links
132 // (e.g. vbd mapped volumes in a XEN vm)
133 {
134 Pathname dpath("/dev/disk/by-label");
135 std::list<Pathname> dlist;
137 {
138 std::list<Pathname>::const_iterator it;
139 for(it = dlist.begin(); it != dlist.end(); ++it)
140 {
142 if( vol_info.isBlk() && vol_info.devMajor() == dev_info.devMajor() &&
143 vol_info.devMinor() == dev_info.devMinor())
144 {
145 DBG << "Specified device name " << dev_name
146 << " is a volume (disk/by-label link "
147 << vol_info.path() << ")"
148 << std::endl;
149 return true;
150 }
151 }
152 }
153 }
154
155 // check if a filesystem volume using the 'blkid' tool
156 // (there is no /dev/disk link for some of them)
158 args.push_back( "blkid" );
159 args.push_back( "-p" );
160 args.push_back( dev_name.asString() );
161
163 cmd >> DBG;
164 if ( cmd.close() != 0 )
165 {
166 ERR << cmd.execError() << endl
167 << "Specified device name " << dev_name
168 << " is not a usable disk volume"
169 << std::endl;
170 return false;
171 }
172 return true;
173 }
174
176 //
177 //
178 // METHOD NAME : MediaDISK::attachTo
179 // METHOD TYPE : PMError
180 //
181 // DESCRIPTION : Asserted that not already attached, and attachPoint is a directory.
182 //
183 void MediaDISK::attachTo(bool next)
184 {
185 if(next)
187 // FIXME
188 // do mount --bind <partition>/<dir> to <to>
189 // mount /dev/<partition> /tmp_mount
190 // mount /tmp_mount/<dir> <to> --bind -o ro
191 // FIXME: try all filesystems
192
193 if(_device.empty())
195
197 if(!dev_info.isBlk())
199#if DELAYED_VERIFY
200 DBG << "Verifying " << _device << " ..." << std::endl;
202 {
204 }
205#endif
206
207 if(_filesystem.empty())
209
210 MediaSourceRef media( new MediaSource(
211 "disk", _device, dev_info.devMajor(), dev_info.devMinor()
212 ));
214
215 if( ret.mediaSource &&
216 ret.attachPoint &&
217 !ret.attachPoint->empty())
218 {
219 DBG << "Using a shared media "
220 << ret.mediaSource->name
221 << " attached on "
222 << ret.attachPoint->path
223 << endl;
224
226 setAttachPoint(ret.attachPoint);
227 setMediaSource(ret.mediaSource);
228 return;
229 }
230
232 MountEntries entries( manager.getMountEntries());
233 MountEntries::const_iterator e;
234 for( e = entries.begin(); e != entries.end(); ++e)
235 {
236 bool is_device = false;
237 std::string dev_path(Pathname(e->src).asString());
239
240 if( dev_path.compare(0, sizeof("/dev/")-1, "/dev/") == 0 &&
241 dev_info(e->src) && dev_info.isBlk())
242 {
243 is_device = true;
244 }
245
246 if( is_device && media->maj_nr == dev_info.devMajor() &&
247 media->min_nr == dev_info.devMinor())
248 {
249 AttachPointRef ap( new AttachPoint(e->dir, false));
250 AttachedMedia am( media, ap);
251 {
252 DBG << "Using a system mounted media "
253 << media->name
254 << " attached on "
255 << ap->path
256 << endl;
257
258 media->iown = false; // mark attachment as foreign
259
260 setMediaSource(media);
262 return;
263 }
264 }
265 }
266
268 {
270 }
271 std::string mountpoint( attachPoint().asString() );
272
273 Mount mount;
274 std::string options = _url.getQueryParam("mountoptions");
275 if(options.empty())
276 {
277 options = "ro";
278 }
279
280 if( !media->bdir.empty())
281 {
282 options += ",bind";
283 mount.mount(media->bdir, mountpoint, "none", options);
284 }
285 else
286 {
287 mount.mount(_device, mountpoint, _filesystem, options);
288 }
289
290 setMediaSource(media);
291
292 // wait for /etc/mtab update ...
293 // (shouldn't be needed)
294 int limit = 3;
295 bool mountsucceeded = false;
296 while( !(mountsucceeded=isAttached()) && --limit)
297 {
298 sleep(1);
299 }
300
301 if( !mountsucceeded)
302 {
304 try
305 {
306 mount.umount(attachPoint().asString());
307 }
308 catch (const MediaException & excpt_r)
309 {
311 }
313 "Unable to verify that the media was mounted",
315 ));
316 }
317 }
318
320 //
321 // METHOD NAME : MediaDISK::isAttached
322 // METHOD TYPE : bool
323 //
324 // DESCRIPTION : Override check if media is attached.
325 //
326 bool
328 {
329 return checkAttached(false);
330 }
331
333 //
334 //
335 // METHOD NAME : MediaDISK::releaseFrom
336 // METHOD TYPE : PMError
337 //
338 // DESCRIPTION : Asserted that media is attached.
339 //
340 void MediaDISK::releaseFrom( const std::string & ejectDev )
341 {
343 if(am.mediaSource && am.mediaSource->iown)
344 {
345 Mount mount;
346 mount.umount(attachPoint().asString());
347 }
348 }
349
351 //
352 // METHOD NAME : MediaDISK::getFile
353 // METHOD TYPE : PMError
354 //
355 // DESCRIPTION : Asserted that media is attached.
356 //
357 void MediaDISK::getFile ( const OnMediaLocation &file ) const
358 {
359 MediaHandler::getFile( file );
360 }
361
363 //
364 // METHOD NAME : MediaDISK::getDir
365 // METHOD TYPE : PMError
366 //
367 // DESCRIPTION : Asserted that media is attached.
368 //
369 void MediaDISK::getDir( const Pathname & dirname, bool recurse_r ) const
370 {
372 }
373
375 //
376 //
377 // METHOD NAME : MediaDISK::getDirInfo
378 // METHOD TYPE : PMError
379 //
380 // DESCRIPTION : Asserted that media is attached and retlist is empty.
381 //
382 void MediaDISK::getDirInfo( std::list<std::string> & retlist,
383 const Pathname & dirname, bool dots ) const
384 {
386 }
387
389 //
390 //
391 // METHOD NAME : MediaDISK::getDirInfo
392 // METHOD TYPE : PMError
393 //
394 // DESCRIPTION : Asserted that media is attached and retlist is empty.
395 //
397 const Pathname & dirname, bool dots ) const
398 {
400 }
401
402 bool MediaDISK::getDoesFileExist( const Pathname & filename ) const
403 {
404 return MediaHandler::getDoesFileExist( filename );
405 }
406
407 } // namespace media
408} // namespace zypp
409// vim: set ts=8 sts=2 sw=2 ai noet:
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition AutoDispose.h:95
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
std::vector< std::string > Arguments
Describes a resource file located on a medium.
Url manipulation class.
Definition Url.h:93
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:226
const std::string & asString() const
String representation.
Definition Pathname.h:93
Attach point of a media source.
void releaseFrom(const std::string &ejectDev) override
Call concrete handler to release the media.
Definition MediaDISK.cc:340
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 MediaDISK.cc:382
std::string _device
Definition MediaDISK.h:30
bool verifyIfDiskVolume(const Pathname &name)
Definition MediaDISK.cc:90
std::string _filesystem
Definition MediaDISK.h:31
void attachTo(bool next=false) override
Call concrete handler to attach the media.
Definition MediaDISK.cc:183
bool isAttached() const override
True if media is attached.
Definition MediaDISK.cc:327
bool getDoesFileExist(const Pathname &filename) const override
check if a file exists
Definition MediaDISK.cc:402
void getDir(const Pathname &dirname, bool recurse_r) const override
Call concrete handler to provide directory content (not recursive!) below attach point.
Definition MediaDISK.cc:369
void getFile(const OnMediaLocation &file) const override
Call concrete handler to provide file below attach point.
Definition MediaDISK.cc:357
MediaDISK(const Url &url_r, const Pathname &attach_point_hint_r)
Definition MediaDISK.cc:53
Just inherits Exception to separate media exceptions.
Abstract base class for 'physical' MediaHandler like MediaCD, etc.
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...
virtual void getFile(const OnMediaLocation &file) const
Call concrete handler to provide file below attach point.
Url url() const
Url used.
virtual bool getDoesFileExist(const Pathname &filename) const =0
check if a file exists
Pathname createAttachPoint() const
Try to create a default / temporary attach point.
void setMediaSource(const MediaSourceRef &ref)
Set new media source reference.
const Url _url
Url to handle.
bool checkAttached(bool matchMountFs) const
Check actual mediaSource attachment against the current mount table of the system.
void removeAttachPoint()
Remove unused attach point.
void setAttachPoint(const Pathname &path, bool temp)
Set a new attach point.
Pathname attachPoint() const
Return the currently used attach point.
virtual void getDir(const Pathname &dirname, bool recurse_r) const =0
Call concrete handler to provide directory content (not recursive!) below attach point.
AttachedMedia findAttachedMedia(const MediaSourceRef &media) const
Ask the media manager if specified media source is already attached.
AttachedMedia attachedMedia() const
Returns the attached media.
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.
Manages access to the 'physical' media, e.g CDROM drives, Disk volumes, directory trees,...
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
std::list< DirEntry > DirContent
Returned by readdir.
Definition PathInfo.h:526
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
Definition PathInfo.cc:610
zypp::RW_pointer< MediaSource > MediaSourceRef
Easy-to use interface to the ZYPP dependency resolver.
std::string asString(const Patch::Category &obj)
Definition Patch.cc:122
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 ERR
Definition Logger.h:102