libzypp 17.31.23
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 //
53 MediaDISK::MediaDISK( const Url & url_r,
54 const Pathname & attach_point_hint_r )
55 : MediaHandler( url_r, attach_point_hint_r,
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
100 PathInfo dev_info(dev_name);
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;
112 if( zypp::filesystem::readdir(dlist, dpath) == 0)
113 {
114 std::list<Pathname>::const_iterator it;
115 for(it = dlist.begin(); it != dlist.end(); ++it)
116 {
117 PathInfo vol_info(*it);
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;
136 if( zypp::filesystem::readdir(dlist, dpath) == 0)
137 {
138 std::list<Pathname>::const_iterator it;
139 for(it = dlist.begin(); it != dlist.end(); ++it)
140 {
141 PathInfo vol_info(*it);
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
196 PathInfo dev_info(_device);
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 ));
213 AttachedMedia ret( findAttachedMedia( media));
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
228 return;
229 }
230
231 MediaManager manager;
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());
238 PathInfo dev_info;
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);
261 setAttachPoint(ap);
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;
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 {
310 ZYPP_CAUGHT(excpt_r);
311 }
313 "Unable to verify that the media was mounted",
314 _device, mountpoint
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 {
371 MediaHandler::getDir( dirname, recurse_r );
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 {
385 MediaHandler::getDirInfo( retlist, dirname, dots );
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 {
399 MediaHandler::getDirInfo( retlist, dirname, dots );
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:
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
std::vector< std::string > Arguments
const std::string & execError() const
Some detail telling why the execution failed, if it failed.
int close()
Wait for the progamm to complete.
Describes a resource file located on a medium.
Url manipulation class.
Definition: Url.h:92
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
Wrapper class for stat/lstat.
Definition: PathInfo.h:221
const Pathname & path() const
Return current Pathname.
Definition: PathInfo.h:246
unsigned int devMinor() const
Definition: PathInfo.cc:251
unsigned int devMajor() const
Definition: PathInfo.cc:241
const std::string & asString() const
String representation.
Definition: Pathname.h:91
bool empty() const
Test for an empty path.
Definition: Pathname.h:114
Attach point of a media source.
Definition: MediaSource.h:106
virtual void releaseFrom(const std::string &ejectDev) override
Call concrete handler to release the media.
Definition: MediaDISK.cc:340
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: 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
virtual void attachTo(bool next=false) override
Call concrete handler to attach the media.
Definition: MediaDISK.cc:183
virtual bool isAttached() const override
True if media is attached.
Definition: MediaDISK.cc:327
virtual bool getDoesFileExist(const Pathname &filename) const override
check if a file exists
Definition: MediaDISK.cc:402
virtual 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
virtual 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.
Definition: MediaHandler.h:51
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.
Definition: MediaHandler.h:503
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.
Definition: MediaHandler.h:113
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,...
Definition: MediaManager.h:454
static std::vector< MountEntry > getMountEntries()
Get current mount entries from /etc/mtab file.
Media source internally used by MediaManager and MediaHandler.
Definition: MediaSource.h:37
Interface to the mount program.
Definition: mount.h:75
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
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
Definition: PathInfo.cc:605
std::list< DirEntry > DirContent
Returned by readdir.
Definition: PathInfo.h:518
zypp::RW_pointer< MediaSource > MediaSourceRef
Definition: MediaSource.h:124
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
A simple structure containing references to a media source and its attach point.
Definition: MediaSource.h:134
MediaSourceRef mediaSource
Definition: MediaSource.h:144
AttachPointRef attachPoint
Definition: MediaSource.h:145
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:436
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:428
#define DBG
Definition: Logger.h:95
#define MIL
Definition: Logger.h:96
#define ERR
Definition: Logger.h:98