libzypp 17.37.10

MediaDISK.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12
13#include <zypp/base/Logger.h>
14#include <zypp/base/String.h>
15#include <zypp-media/Mount>
16#include <zypp/media/MediaDISK.h>
17#include <zypp/media/MediaManager.h>
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
28 using std::endl;
29
30/*
31** verify devices names as late as possible (while attach)
32*/
33#define DELAYED_VERIFY 1
34
35
36 namespace 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 MirroredOrigin &origin_r,
54 const Pathname & attach_point_hint_r )
55 : MediaHandler( origin_r, attach_point_hint_r,
56 origin_r.authority().url().getPathName(), // urlpath below attachpoint
57 false ) // does_download
58 {
59 MIL << "MediaDISK::MediaDISK(" << origin_r.authority().url() << ", " << attach_point_hint_r << ")" << endl;
60
61 _device = Pathname(origin_r.authority().url().getQueryParam("device")).asString();
62 if( _device.empty())
63 {
64 ERR << "Media url does not contain a device specification" << std::endl;
65 ZYPP_THROW(MediaBadUrlEmptyDestinationException(origin_r.authority().url()));
66 }
67#if DELAYED_VERIFY
68 DBG << "Verify of " << _device << " delayed" << std::endl;
69#else
70 if( !verifyIfDiskVolume( _device))
71 {
72 ZYPP_THROW(MediaBadUrlEmptyDestinationException(_origin.authority().url()));
73 }
74#endif
75
76 _filesystem = origin_r.authority().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 //
90 bool MediaDISK::verifyIfDiskVolume(const Pathname &dev_name)
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)
157 ExternalProgram::Arguments args;
158 args.push_back( "blkid" );
159 args.push_back( "-p" );
160 args.push_back( dev_name.asString() );
161
162 ExternalProgram cmd( args, ExternalProgram::Stderr_To_Stdout );
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)
186 ZYPP_THROW(MediaNotSupportedException(url()));
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())
194 ZYPP_THROW(MediaBadUrlEmptyDestinationException(url()));
195
196 PathInfo dev_info(_device);
197 if(!dev_info.isBlk())
198 ZYPP_THROW(MediaBadUrlEmptyDestinationException(url()));
199#if DELAYED_VERIFY
200 DBG << "Verifying " << _device << " ..." << std::endl;
201 if( !verifyIfDiskVolume( _device))
202 {
203 ZYPP_THROW(MediaBadUrlEmptyDestinationException(_origin.authority().url()));
204 }
205#endif
206
207 if(_filesystem.empty())
208 ZYPP_THROW(MediaBadUrlEmptyFilesystemException(url()));
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
225 removeAttachPoint();
226 setAttachPoint(ret.attachPoint);
227 setMediaSource(ret.mediaSource);
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
267 if( !isUseableAttachPoint( attachPoint() ) )
268 {
269 setAttachPoint( createAttachPoint(), true );
270 }
271 std::string mountpoint( attachPoint().asString() );
272
273 Mount mount;
274 std::string options = _origin.authority().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 {
303 setMediaSource(MediaSourceRef());
304 try
305 {
306 mount.umount(attachPoint().asString());
307 }
308 catch (const MediaException & excpt_r)
309 {
310 ZYPP_CAUGHT(excpt_r);
311 }
312 ZYPP_THROW(MediaMountException(
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
327 MediaDISK::isAttached() const
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 {
342 AttachedMedia am( attachedMedia());
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 //
396 void MediaDISK::getDirInfo( filesystem::DirContent & retlist,
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:
MediaDISK.h
MediaManager.h
zypp::ExternalProgram
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
Definition ExternalProgram.h:64
zypp::ExternalProgram::close
int close() override
Wait for the progamm to complete.
Definition ExternalProgram.cc:357
zypp::ExternalProgram::Arguments
std::vector< std::string > Arguments
Definition ExternalProgram.h:68
zypp::ExternalProgram::execError
const std::string & execError() const
Some detail telling why the execution failed, if it failed.
Definition ExternalProgram.cc:473
zypp::ExternalProgram::Stderr_To_Stdout
@ Stderr_To_Stdout
Definition ExternalProgram.h:77
zypp::MirroredOrigin
Manages a data source characterized by an authoritative URL and a list of mirror URLs.
Definition MirroredOrigin.h:170
zypp::MirroredOrigin::authority
const OriginEndpoint & authority() const
Definition MirroredOrigin.cc:184
zypp::OnMediaLocation
Describes a resource file located on a medium.
Definition onmedialocation.h:37
zypp::OriginEndpoint::url
const zypp::Url & url() const
Definition MirroredOrigin.cc:51
zypp::Url::getQueryParam
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
zypp::filesystem::PathInfo
Wrapper class for stat/lstat.
Definition PathInfo.h:226
zypp::filesystem::PathInfo::isBlk
bool isBlk() const
Definition PathInfo.h:299
zypp::filesystem::PathInfo::path
const Pathname & path() const
Return current Pathname.
Definition PathInfo.h:251
zypp::filesystem::PathInfo::devMinor
unsigned int devMinor() const
Definition PathInfo.cc:252
zypp::filesystem::PathInfo::devMajor
unsigned int devMajor() const
Definition PathInfo.cc:242
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:47
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition Pathname.h:93
zypp::filesystem::Pathname::empty
bool empty() const
Test for an empty path.
Definition Pathname.h:116
zypp::media::AttachPoint
Attach point of a media source.
Definition MediaSource.h:107
zypp::media::MediaBadUrlEmptyDestinationException
Definition mediaexception.h:330
zypp::media::MediaBadUrlEmptyFilesystemException
Definition mediaexception.h:319
zypp::media::MediaDISK::releaseFrom
void releaseFrom(const std::string &ejectDev) override
Call concrete handler to release the media.
Definition MediaDISK.cc:340
zypp::media::MediaDISK::getDirInfo
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
zypp::media::MediaDISK::_device
std::string _device
Definition MediaDISK.h:30
zypp::media::MediaDISK::verifyIfDiskVolume
bool verifyIfDiskVolume(const Pathname &name)
Definition MediaDISK.cc:90
zypp::media::MediaDISK::_filesystem
std::string _filesystem
Definition MediaDISK.h:31
zypp::media::MediaDISK::attachTo
void attachTo(bool next=false) override
Call concrete handler to attach the media.
Definition MediaDISK.cc:183
zypp::media::MediaDISK::isAttached
bool isAttached() const override
True if media is attached.
Definition MediaDISK.cc:327
zypp::media::MediaDISK::getDoesFileExist
bool getDoesFileExist(const Pathname &filename) const override
check if a file exists
Definition MediaDISK.cc:402
zypp::media::MediaDISK::getDir
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
zypp::media::MediaDISK::MediaDISK
MediaDISK(const MirroredOrigin &origin_r, const Pathname &attach_point_hint_r)
Definition MediaDISK.cc:53
zypp::media::MediaDISK::getFile
void getFile(const OnMediaLocation &file) const override
Call concrete handler to provide file below attach point.
Definition MediaDISK.cc:357
zypp::media::MediaException
Just inherits Exception to separate media exceptions.
Definition mediaexception.h:37
zypp::media::MediaHandler::isUseableAttachPoint
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...
Definition MediaHandler.cc:416
zypp::media::MediaHandler::getFile
virtual void getFile(const OnMediaLocation &file) const
Call concrete handler to provide file below attach point.
Definition MediaHandler.cc:1188
zypp::media::MediaHandler::MediaHandler
MediaHandler(MirroredOrigin origin_r, const Pathname &attach_point_r, Pathname urlpath_below_attachpoint_r, const bool does_download_r)
If the concrete media handler provides a nonempty attach_point, it must be an existing directory.
Definition MediaHandler.cc:55
zypp::media::MediaHandler::_origin
MirroredOrigin _origin
Contains the authority URL and mirrors.
Definition MediaHandler.h:112
zypp::media::MediaHandler::url
Url url() const
Primary Url used.
Definition MediaHandler.h:502
zypp::media::MediaHandler::getDoesFileExist
virtual bool getDoesFileExist(const Pathname &filename) const =0
check if a file exists
Definition MediaHandler.cc:1326
zypp::media::MediaHandler::createAttachPoint
Pathname createAttachPoint() const
Try to create a default / temporary attach point.
Definition MediaHandler.cc:312
zypp::media::MediaHandler::setMediaSource
void setMediaSource(const MediaSourceRef &ref)
Set new media source reference.
Definition MediaHandler.cc:432
zypp::media::MediaHandler::checkAttached
bool checkAttached(bool matchMountFs) const
Check actual mediaSource attachment against the current mount table of the system.
Definition MediaHandler.cc:479
zypp::media::MediaHandler::removeAttachPoint
void removeAttachPoint()
Remove unused attach point.
Definition MediaHandler.cc:143
zypp::media::MediaHandler::setAttachPoint
void setAttachPoint(const Pathname &path, bool temp)
Set a new attach point.
Definition MediaHandler.cc:200
zypp::media::MediaHandler::attachPoint
Pathname attachPoint() const
Return the currently used attach point.
Definition MediaHandler.cc:185
zypp::media::MediaHandler::getDir
virtual void getDir(const Pathname &dirname, bool recurse_r) const =0
Call concrete handler to provide directory content (not recursive!) below attach point.
Definition MediaHandler.cc:1219
zypp::media::MediaHandler::findAttachedMedia
AttachedMedia findAttachedMedia(const MediaSourceRef &media) const
Ask the media manager if specified media source is already attached.
Definition MediaHandler.cc:269
zypp::media::MediaHandler::attachedMedia
AttachedMedia attachedMedia() const
Returns the attached media.
Definition MediaHandler.cc:448
zypp::media::MediaHandler::getDirInfo
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.
Definition MediaHandler.cc:1241
zypp::media::MediaManager
Manages access to the 'physical' media, e.g CDROM drives, Disk volumes, directory trees,...
Definition MediaManager.h:454
zypp::media::MediaManager::getMountEntries
static std::vector< MountEntry > getMountEntries()
Get current mount entries from /etc/mtab file.
Definition MediaManager.cc:887
zypp::media::MediaMountException
Definition mediaexception.h:56
zypp::media::MediaNotSupportedException
Definition mediaexception.h:352
zypp::media::MediaSource
Media source internally used by MediaManager and MediaHandler.
Definition MediaSource.h:38
zypp::media::Mount
Interface to the mount program.
Definition mount.h:76
zypp::media::Mount::umount
void umount(const std::string &path)
umount device
Definition mount.cc:117
zypp::media::Mount::mount
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
zypp::filesystem::DirContent
std::list< DirEntry > DirContent
Returned by readdir.
Definition PathInfo.h:526
zypp::filesystem::readdir
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::media
Definition MediaNetworkRequestExecutor.h:22
zypp::media::MediaSourceRef
zypp::RW_pointer< MediaSource > MediaSourceRef
Definition MediaSource.h:125
zypp::media::AttachPointRef
zypp::RW_pointer< AttachPoint > AttachPointRef
Definition MediaSource.h:126
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition Application.cc:20
zypp::asString
std::string asString(const Patch::Category &obj)
Definition Patch.cc:122
zypp::media::AttachedMedia
A simple structure containing references to a media source and its attach point.
Definition MediaSource.h:135
zypp::media::AttachedMedia::mediaSource
MediaSourceRef mediaSource
Definition MediaSource.h:145
zypp::media::AttachedMedia::attachPoint
AttachPointRef attachPoint
Definition MediaSource.h:146
ZYPP_CAUGHT
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:475
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
DBG
#define DBG
Definition Logger.h:99
MIL
#define MIL
Definition Logger.h:100
ERR
#define ERR
Definition Logger.h:102
Logger.h
String.h