libzypp 17.37.17
MediaCD.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12extern "C"
13{
14#include <sys/ioctl.h>
15#include <linux/cdrom.h>
16#if HAVE_UDEV
17#include <libudev.h>
18#endif
19}
20
21#include <cstring> // strerror
22#include <cstdlib> // getenv
23#include <iostream>
24
25#include <zypp/base/Logger.h>
27#include <zypp-media/Mount>
28#include <zypp-media/CDTools>
29#include <zypp/media/MediaCD.h>
31#include <zypp/Url.h>
32#include <zypp/AutoDispose.h>
33
34using std::endl;
35
36/*
37** if to throw exception on eject errors or ignore them
38*/
39#define REPORT_EJECT_ERRORS 0
40
41
43namespace zypp
44{
46 namespace media
47 {
48
50 namespace
51 {
52 using DeviceList = std::list<MediaSource>;
53
59 DeviceList systemDetectDevices( bool supportingDVD_r )
60 {
61 DeviceList detected;
62
63#ifdef HAVE_UDEV
64 // http://www.kernel.org/pub/linux/utils/kernel/hotplug/libudev/index.html
65 zypp::AutoDispose<struct udev *> udev( ::udev_new(), ::udev_unref );
66 if ( ! udev )
67 {
68 ERR << "Can't create udev context." << endl;
69 return DeviceList();
70 }
71
72 zypp::AutoDispose<struct udev_enumerate *> enumerate( ::udev_enumerate_new(udev), ::udev_enumerate_unref );
73 if ( ! enumerate )
74 {
75 ERR << "Can't create udev list entry." << endl;
76 return DeviceList();
77 }
78
79 ::udev_enumerate_add_match_subsystem( enumerate, "block" );
80 ::udev_enumerate_add_match_property( enumerate, "ID_CDROM", "1" );
81 ::udev_enumerate_scan_devices( enumerate );
82
83 struct udev_list_entry * entry = 0;
84 udev_list_entry_foreach( entry, ::udev_enumerate_get_list_entry( enumerate ) )
85 {
86 zypp::AutoDispose<struct udev_device *> device( ::udev_device_new_from_syspath( ::udev_enumerate_get_udev( enumerate ),
87 ::udev_list_entry_get_name( entry ) ),
88 ::udev_device_unref );
89 if ( ! device )
90 {
91 ERR << "Can't create udev device." << endl;
92 continue;
93 }
94
95 if ( supportingDVD_r && ! ::udev_device_get_property_value( device, "ID_CDROM_DVD" ) )
96 {
97 continue; // looking for dvd only
98 }
99
100 const char * devnodePtr( ::udev_device_get_devnode( device ) );
101 if ( ! devnodePtr )
102 {
103 ERR << "Got NULL devicenode." << endl;
104 continue;
105 }
106
107 // In case we need it someday:
108 //const char * mountpath = ::udev_device_get_property_value( device, "FSTAB_DIR" );
109
110 PathInfo devnode( devnodePtr );
111 if ( devnode.isBlk() )
112 {
113 MediaSource media( "cdrom", devnode.path().asString(), devnode.devMajor(), devnode.devMinor() );
114 DBG << "Found (udev): " << media << std::endl;
115 detected.push_back( media );
116 }
117 }
118 if ( detected.empty() )
119 {
120 WAR << "Did not find any CD/DVD device." << endl;
121 }
122#endif
123 return detected;
124 }
125
126 } // namespace
128
129
130 MediaCD::MediaCD(MirroredOrigin origin_r, const Pathname & attach_point_hint_r )
131 : MediaHandler( origin_r, attach_point_hint_r, origin_r.authority().url().getPathName(), false )
132 , _lastdev( -1 )
133 , _lastdev_tried( -1 )
134 {
135 MIL << "MediaCD::MediaCD(" << url() << ", " << attach_point_hint_r << ")" << endl;
136
137 const auto &authorityUrl = _origin.authority().url();
138 if ( _origin.scheme() != "dvd" && _origin.scheme() != "cd" )
139 {
140 ERR << "Unsupported schema in the Url: " << authorityUrl.asString() << endl;
142 }
143
144 std::string devices = authorityUrl.getQueryParam( "devices" );
145 if ( ! devices.empty() )
146 {
147 std::vector<std::string> words;
148 str::split( devices, std::back_inserter(words), "," );
149 for ( const std::string & device : words )
150 {
151 if ( device.empty() )
152 continue;
153
154 MediaSource media( "cdrom", device, 0, 0 );
155 _devices.push_back( media );
156 DBG << "use device (delayed verify)" << device << endl;
157 }
158 }
159 else
160 {
161 DBG << "going to use on-demand device list" << endl;
162 return;
163 }
164
165 if ( _devices.empty() )
166 {
167 ERR << "Unable to find any cdrom drive for " << authorityUrl.asString() << endl;
169 }
170 }
171
173 //
174 //
175 // METHOD NAME : MediaCD::openTray
176 // METHOD TYPE : bool
177 //
178 bool MediaCD::openTray( const std::string & device_r )
179 {
180 return CDTools::openTray(device_r);
181 }
182
184 //
185 //
186 // METHOD NAME : MediaCD::closeTray
187 // METHOD TYPE : bool
188 //
189 bool MediaCD::closeTray( const std::string & device_r )
190 {
191 return CDTools::closeTray(device_r);
192 }
193
194
195 MediaCD::DeviceList MediaCD::detectDevices( bool supportingDVD_r ) const
196 {
197 DeviceList detected( systemDetectDevices( supportingDVD_r ) );
198
199 if ( detected.empty() )
200 {
201 WAR << "CD/DVD drive detection with UDEV failed! Guessing..." << std::endl;
202 PathInfo dvdinfo( "/dev/dvd" );
203 PathInfo cdrinfo( "/dev/cdrom" );
204 if ( dvdinfo.isBlk() )
205 {
206 MediaSource media( "cdrom", dvdinfo.path().asString(), dvdinfo.devMajor(), dvdinfo.devMinor() );
207 DBG << "Found (GUESS): " << media << std::endl;
208 detected.push_back( media );
209 }
210 if ( cdrinfo.isBlk()
211 && ! ( cdrinfo.devMajor() == dvdinfo.devMajor() && cdrinfo.devMinor() == dvdinfo.devMinor() ) )
212 {
213 MediaSource media( "cdrom", cdrinfo.path().asString(), cdrinfo.devMajor(), cdrinfo.devMinor() );
214 DBG << "Found (GUESS): " << media << std::endl;
215 detected.push_back( media );
216 }
217 }
218
219 // NOTE: On the fly build on-demand device list. Code was moved to
220 // here to get rid of code duplication, while keeping the ABI. Acuallty
221 // this code should be moved to a _devices accessor method.
222 if ( _devices.empty() )
223 {
224 DBG << "creating on-demand device list" << endl;
225 //default is /dev/cdrom; for dvd: /dev/dvd if it exists
226 std::string device( "/dev/cdrom" );
227 if ( _origin.scheme() == "dvd" && PathInfo( "/dev/dvd" ).isBlk() )
228 {
229 device = "/dev/dvd";
230 }
231
232 PathInfo dinfo( device );
233 if ( dinfo.isBlk() )
234 {
235 MediaSource media( "cdrom", device, dinfo.devMajor(), dinfo.devMinor() );
236 if ( detected.empty() )
237 {
238 _devices.push_front( media ); // better try this than nothing
239 }
240 else
241 {
242 for( const auto & d : detected )
243 {
244 // /dev/cdrom or /dev/dvd to the front
245 if ( media.equals( d ) )
246 _devices.push_front( d );
247 else
248 _devices.push_back( d );
249 }
250 }
251 }
252 else
253 {
254 // no /dev/cdrom or /dev/dvd link
255 _devices = detected;
256 }
257 }
258
259 return detected;
260 }
261
262
264 //
265 //
266 // METHOD NAME : MediaCD::attachTo
267 // METHOD TYPE : PMError
268 //
269 // DESCRIPTION : Asserted that not already attached, and attachPoint is a directory.
270 //
271 void MediaCD::attachTo( bool next )
272 {
273 DBG << "next " << next << " last " << _lastdev << " last tried " << _lastdev_tried << endl;
274 if ( next && _lastdev == -1 )
276
277 const auto &authorityUrl = _origin.authority().url();
278
279 // This also fills the _devices list on demand
280 DeviceList detected( detectDevices( authorityUrl.getScheme() == "dvd" ? true : false ) );
281
282 Mount mount;
284
285 std::string options = authorityUrl.getQueryParam( "mountoptions" );
286 if ( options.empty() )
287 {
288 options="ro";
289 }
290
291 //TODO: make configurable
292 std::list<std::string> filesystems;
293
294 filesystems.push_back("iso9660");
295
296 // if DVD, try UDF filesystem after iso9660
297 if ( authorityUrl.getScheme() == "dvd" )
298 filesystems.push_back("udf");
299
300 // try all devices in sequence
301 int count = 0;
302 std::string mountpoint( attachPoint().asString() );
303 bool mountsucceeded = false;
304 for ( DeviceList::iterator it = _devices.begin() ; ! mountsucceeded && it != _devices.end() ; ++it, ++count )
305 {
306 DBG << "count " << count << endl;
307 if (next && count <=_lastdev_tried )
308 {
309 DBG << "skipping device " << it->name << endl;
310 continue;
311 }
312 _lastdev_tried = count;
313
314 // bnc#755815: _devices contains either devices passed as url option
315 // or autodetected ones. Accept both as long as they are block
316 // devices.
317 MediaSource temp( *it );
318 PathInfo dinfo( temp.name );
319 if ( ! dinfo.isBlk() )
320 {
321 WAR << "skipping non block device: " << dinfo << endl;
322 continue;
323 }
324 DBG << "trying device " << dinfo << endl;
325
326 temp.maj_nr = dinfo.devMajor();
327 temp.min_nr = dinfo.devMinor();
328 MediaSourceRef media( new MediaSource(temp));
330
331 if( ret.mediaSource && ret.attachPoint &&
332 !ret.attachPoint->empty())
333 {
334 DBG << "Using a shared media "
335 << ret.mediaSource->name
336 << " attached on "
337 << ret.attachPoint->path
338 << endl;
342 _lastdev = count;
343 mountsucceeded = true;
344 break;
345 }
346
347 {
348 MediaManager manager;
349 MountEntries entries( manager.getMountEntries());
350 MountEntries::const_iterator e;
351 for( e = entries.begin(); e != entries.end(); ++e)
352 {
353 bool is_device = false;
354 std::string dev_path(Pathname(e->src).asString());
355 PathInfo dev_info;
356
357 if( dev_path.compare(0, sizeof("/dev/")-1, "/dev/") == 0 &&
358 dev_info(e->src) && dev_info.isBlk())
359 {
360 is_device = true;
361 }
362
363 if( is_device && media->maj_nr == dev_info.devMajor() &&
364 media->min_nr == dev_info.devMinor())
365 {
366 AttachPointRef ap( new AttachPoint(e->dir, false));
367 AttachedMedia am( media, ap);
368 {
369 DBG << "Using a system mounted media "
370 << media->name
371 << " attached on "
372 << ap->path
373 << endl;
374
375 media->iown = false; // mark attachment as foreign
376
378 setAttachPoint(ap);
379 _lastdev = count;
380 mountsucceeded = true;
381 break;
382 }
383 }
384 }
385 if( mountsucceeded)
386 break;
387 }
388
389 // close tray
390 closeTray( it->name );
391
392 // try all filesystems in sequence
393 for(std::list<std::string>::iterator fsit = filesystems.begin()
394 ; !mountsucceeded && fsit != filesystems.end()
395 ; ++fsit)
396 {
397 try
398 {
400 {
402 mountpoint = attachPoint().asString();
403 }
404
405 mount.mount(it->name, mountpoint, *fsit, options);
406
408
409 // wait for /etc/mtab update ...
410 // (shouldn't be needed)
411 int limit = 2;
412 while( !(mountsucceeded=isAttached()) && --limit)
413 {
414 WAR << "Wait for /proc/mounts update and retry...." << endl;
415 sleep(1);
416 }
417
418 if( mountsucceeded)
419 {
420 _lastdev = count;
421 }
422 else
423 {
425 try
426 {
427 mount.umount(attachPoint().asString());
428 }
429 catch (const MediaException & excpt_r)
430 {
431 ZYPP_CAUGHT(excpt_r);
432 }
434 "Unable to verify that the media was mounted",
435 it->name, mountpoint
436 ));
437 }
438 }
439 catch (const MediaMountException &e)
440 {
441 merr = e;
443 ZYPP_CAUGHT(e);
444 }
445 catch (const MediaException & excpt_r)
446 {
448 ZYPP_CAUGHT(excpt_r);
449 }
450 } // for filesystems
451 } // for _devices
452
453 if (!mountsucceeded)
454 {
455 _lastdev = -1;
456
457 if( !merr.mountOutput().empty())
458 {
460 authorityUrl.asString(),
461 mountpoint,
462 merr.mountOutput()));
463 }
464 else
465 {
466 ZYPP_THROW(MediaMountException("Mounting media failed",
467 authorityUrl.asString(), mountpoint));
468 }
469 }
470 DBG << _lastdev << " " << count << endl;
471 }
472
473
475 //
476 //
477 // METHOD NAME : MediaCD::releaseFrom
478 // METHOD TYPE : PMError
479 //
480 // DESCRIPTION : Asserted that media is attached.
481 //
482 void MediaCD::releaseFrom( const std::string & ejectDev )
483 {
484 Mount mount;
485 try
486 {
488 if(am.mediaSource && am.mediaSource->iown)
489 mount.umount(am.attachPoint->path.asString());
490 }
491 catch (const Exception & excpt_r)
492 {
493 ZYPP_CAUGHT(excpt_r);
494 if (!ejectDev.empty())
495 {
496 forceRelaseAllMedia(false);
497 if(openTray( ejectDev ))
498 return;
499 }
500 ZYPP_RETHROW(excpt_r);
501 }
502
503 // eject device
504 if (!ejectDev.empty())
505 {
506 forceRelaseAllMedia(false);
507 if( !openTray( ejectDev ))
508 {
509#if REPORT_EJECT_ERRORS
511#endif
512 }
513 }
514 }
515
517 //
518 //
519 // METHOD NAME : MediaCD::forceEject
520 // METHOD TYPE : void
521 //
522 // Asserted that media is not attached.
523 //
524 void MediaCD::forceEject( const std::string & ejectDev_r )
525 {
526#if REPORT_EJECT_ERRORS
527 bool ejected = false;
528#endif
529 if ( ! isAttached() ) // no device mounted in this instance
530 {
531 // This also fills the _devices list on demand
532 DeviceList detected( detectDevices( _origin.scheme() == "dvd" ? true : false ) );
533 for_( it, _devices.begin(), _devices.end() )
534 {
535 MediaSourceRef media( new MediaSource( *it ) );
536 if ( media->name != ejectDev_r )
537 continue;
538
539 // bnc#755815: _devices contains either devices passed as url option
540 // or autodetected ones. Accept both as long as they are block
541 // devices.
542 PathInfo dinfo( media->name );
543 if( ! dinfo.isBlk() )
544 {
545 WAR << "skipping non block device: " << dinfo << endl;
546 continue;
547 }
548 DBG << "trying device " << dinfo << endl;
549
550 // FIXME: we have also to check if it is mounted in the system
552 if( !ret.mediaSource )
553 {
554 forceRelaseAllMedia( media, false );
555 if ( openTray( it->name ) )
556 {
557#if REPORT_EJECT_ERRORS
558 ejected = true;
559#endif
560 break; // on 1st success
561 }
562 }
563 }
564 }
565#if REPORT_EJECT_ERRORS
566 if( !ejected)
567 {
569 }
570#endif
571 }
572
574 //
575 // METHOD NAME : MediaCD::isAttached
576 // METHOD TYPE : bool
577 //
578 // DESCRIPTION : Override check if media is attached.
579 //
580 bool
582 {
583 return checkAttached(false);
584 }
585
587 //
588 // METHOD NAME : MediaCD::getFile
589 // METHOD TYPE : PMError
590 //
591 // DESCRIPTION : Asserted that media is attached.
592 //
593 void MediaCD::getFile( const OnMediaLocation &file ) const
594 {
595 MediaHandler::getFile( file );
596 }
597
599 //
600 // METHOD NAME : MediaCD::getDir
601 // METHOD TYPE : PMError
602 //
603 // DESCRIPTION : Asserted that media is attached.
604 //
605 void MediaCD::getDir( const Pathname & dirname, bool recurse_r ) const
606 {
607 MediaHandler::getDir( dirname, recurse_r );
608 }
609
611 //
612 //
613 // METHOD NAME : MediaCD::getDirInfo
614 // METHOD TYPE : PMError
615 //
616 // DESCRIPTION : Asserted that media is attached and retlist is empty.
617 //
618 void MediaCD::getDirInfo( std::list<std::string> & retlist,
619 const Pathname & dirname, bool dots ) const
620 {
621 MediaHandler::getDirInfo( retlist, dirname, dots );
622 }
623
625 //
626 //
627 // METHOD NAME : MediaCD::getDirInfo
628 // METHOD TYPE : PMError
629 //
630 // DESCRIPTION : Asserted that media is attached and retlist is empty.
631 //
632 void MediaCD::getDirInfo( filesystem::DirContent & retlist, const Pathname & dirname, bool dots ) const
633 {
634 MediaHandler::getDirInfo( retlist, dirname, dots );
635 }
636
637
638 bool MediaCD::getDoesFileExist( const Pathname & filename ) const
639 {
640 return MediaHandler::getDoesFileExist( filename );
641 }
642
643
645 {
646 if (_devices.size() == 0)
647 return false;
648 else if (_lastdev_tried < 0)
649 return true;
650
651 return (unsigned) _lastdev_tried < _devices.size() - 1;
652 }
653
654
655 void MediaCD::getDetectedDevices( std::vector<std::string> & devices, unsigned int & index ) const
656 {
657 if ( ! devices.empty() )
658 devices.clear();
659
660 if ( _devices.empty() )
661 // This also fills the _devices list on demand
662 detectDevices( _origin.scheme() == "dvd" ? true : false );
663
664 for ( const auto & it : _devices )
665 devices.push_back( it.name );
666
667 index = ( _lastdev >= 0 ? (unsigned)_lastdev : 0 );
668
669 MIL << "got " << devices.size() << " detected devices, current: "
670 << (index < devices.size() ? devices[index] : "<none>")
671 << "(" << index << ")" << endl;
672 }
673
674 } // namespace media
676} // namespace zypp
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition AutoDispose.h:95
Base class for Exception.
Definition Exception.h:153
Manages a data source characterized by an authoritative URL and a list of mirror URLs.
Describes a resource file located on a medium.
Wrapper class for stat/lstat.
Definition PathInfo.h:226
const Pathname & path() const
Return current Pathname.
Definition PathInfo.h:251
unsigned int devMinor() const
Definition PathInfo.cc:252
unsigned int devMajor() const
Definition PathInfo.cc:242
const std::string & asString() const
String representation.
Definition Pathname.h:93
Attach point of a media source.
static bool openTray(const std::string &device_r)
Definition cdtools.cc:33
static bool closeTray(const std::string &device_r)
Definition cdtools.cc:86
static bool closeTray(const std::string &device_r)
Definition MediaCD.cc:189
bool isAttached() const override
True if media is attached.
Definition MediaCD.cc:581
MediaCD(MirroredOrigin origin_r, const Pathname &attach_point_hint_r)
Definition MediaCD.cc:130
void forceEject(const std::string &ejectDev) override
Call concrete handler to physically eject the media (i.e.
Definition MediaCD.cc:524
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 MediaCD.cc:618
void getDetectedDevices(std::vector< std::string > &devices, unsigned int &index) const override
Fill in a vector of detected ejectable devices and the index of the currently attached device within ...
Definition MediaCD.cc:655
void getFile(const OnMediaLocation &file) const override
Call concrete handler to provide file below attach point.
Definition MediaCD.cc:593
void getDir(const Pathname &dirname, bool recurse_r) const override
Call concrete handler to provide directory content (not recursive!) below attach point.
Definition MediaCD.cc:605
void releaseFrom(const std::string &ejectDev) override
Call concrete handler to release the media.
Definition MediaCD.cc:482
bool getDoesFileExist(const Pathname &filename) const override
check if a file exists
Definition MediaCD.cc:638
std::list< MediaSource > DeviceList
Definition MediaCD.h:31
int _lastdev
number of last successful mounted device in list
Definition MediaCD.h:36
static bool openTray(const std::string &device_r)
Definition MediaCD.cc:178
DeviceList detectDevices(bool supportingDVD) const
Definition MediaCD.cc:195
bool hasMoreDevices() override
Check if the media has one more device available for attach(true).
Definition MediaCD.cc:644
DeviceList _devices
list of devices to try to mount
Definition MediaCD.h:33
void attachTo(bool next=false) override
Call concrete handler to attach the media.
Definition MediaCD.cc:271
Just inherits Exception to separate media exceptions.
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.
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.
MirroredOrigin _origin
Contains the authority URL and mirrors.
Url url() const
Primary 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.
void forceRelaseAllMedia(bool matchMountFs)
Call to this function will try to release all media matching the currenlty attached media source,...
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,...
static std::vector< MountEntry > getMountEntries()
Get current mount entries from /etc/mtab file.
const std::string & mountError() const
const std::string & mountOutput() const
Media source internally used by MediaManager and MediaHandler.
Definition MediaSource.h:38
unsigned int min_nr
A minor number if source is a device.
Definition MediaSource.h:91
unsigned int maj_nr
A major number if source is a device.
Definition MediaSource.h:90
std::string name
A media handler specific source name.
Definition MediaSource.h:93
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
zypp::RW_pointer< MediaSource > MediaSourceRef
zypp::RW_pointer< AttachPoint > AttachPointRef
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", const Trim trim_r=NO_TRIM)
Split line_r into words.
Definition String.h:602
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 for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition Easy.h:27
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition Exception.h:479
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:475
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
#define DBG
Definition Logger.h:99
#define MIL
Definition Logger.h:100
#define ERR
Definition Logger.h:102
#define WAR
Definition Logger.h:101