/** \file zypp/media/MediaCD.cc
*
*/
+extern "C"
+{
+#include <sys/ioctl.h>
+#include <linux/cdrom.h>
+#include <libudev.h>
+}
+#include <cstring> // strerror
+#include <cstdlib> // getenv
#include <iostream>
#include "zypp/base/Logger.h"
#include "zypp/media/MediaCD.h"
#include "zypp/media/MediaManager.h"
#include "zypp/Url.h"
-#include "zypp/target/hal/HalContext.h"
+#include "zypp/AutoDispose.h"
-#include <cstring> // strerror
-#include <cstdlib> // getenv
-#include <errno.h>
-#include <dirent.h>
-
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h> // geteuid, ...
-
-#include <linux/cdrom.h>
-
-/*
-** try umount of foreign (user/automounter) media on eject
-** 0 = don't force, 1 = automounted only, 2 == all
-*/
-#define FORCE_RELEASE_FOREIGN 2
-
-/*
-** Reuse foreign (user/automounter) mount points.
-** 0 = don't use, 1 = automounted only, 2 = all
-*/
-#define REUSE_FOREIGN_MOUNTS 2
/*
** if to throw exception on eject errors or ignore them
// METHOD NAME : MediaCD::detectDevices
// METHOD TYPE : MediaCD::DeviceList
//
- MediaCD::DeviceList
- MediaCD::detectDevices(bool supportingDVD) const
+ MediaCD::DeviceList MediaCD::detectDevices( bool supportingDVD ) const
{
- DeviceList detected;
+ zypp::AutoDispose<struct udev *> udev( ::udev_new(), ::udev_unref );
+ if ( ! udev )
+ {
+ ERR << "Can't create udev context." << endl;
+ return DeviceList();
+ }
-#ifndef NO_HALa
- using namespace zypp::target::hal;
- try
+ zypp::AutoDispose<struct udev_enumerate *> enumerate( ::udev_enumerate_new(udev), ::udev_enumerate_unref );
+ if ( ! enumerate )
{
- HalContext hal(true);
+ ERR << "Can't create udev list entry." << endl;
+ return DeviceList();
+ }
- std::vector<std::string> drv_udis;
- drv_udis = hal.findDevicesByCapability("storage.cdrom");
+ ::udev_enumerate_add_match_subsystem( enumerate, "block" );
+ ::udev_enumerate_add_match_property( enumerate, "ID_CDROM", "1" );
+ ::udev_enumerate_scan_devices( enumerate );
- DBG << "Found " << drv_udis.size() << " cdrom drive udis" << std::endl;
- for(size_t d = 0; d < drv_udis.size(); d++)
+ DeviceList detected;
+ struct udev_list_entry * entry = 0;
+ udev_list_entry_foreach( entry, ::udev_enumerate_get_list_entry( enumerate ) )
+ {
+ zypp::AutoDispose<struct udev_device *> device( ::udev_device_new_from_syspath( ::udev_enumerate_get_udev( enumerate ),
+ ::udev_list_entry_get_name( entry ) ),
+ ::udev_device_unref );
+ if ( ! device )
{
- HalDrive drv( hal.getDriveFromUDI( drv_udis[d]));
+ ERR << "Can't create udev device." << endl;
+ continue;
+ }
- if( drv)
- {
- bool supportsDVD=false;
- if( supportingDVD)
- {
- std::vector<std::string> caps;
- try {
- caps = drv.getCdromCapabilityNames();
- }
- catch(const HalException &e)
- {
- ZYPP_CAUGHT(e);
- }
+ if ( supportingDVD && ! ::udev_device_get_property_value( device, "ID_CDROM_DVD" ) )
+ {
+ continue; // looking for dvd only
+ }
- std::vector<std::string>::const_iterator ci;
- for( ci=caps.begin(); ci != caps.end(); ++ci)
- {
- if( *ci == "dvd")
- supportsDVD = true;
- }
- }
+ const char * devnodePtr( ::udev_device_get_devnode( device ) );
+ if ( ! devnodePtr )
+ {
+ ERR << "Got NULL devicenode." << endl;
+ continue;
+ }
- MediaSource media("cdrom", drv.getDeviceFile(),
- drv.getDeviceMajor(),
- drv.getDeviceMinor());
- DBG << "Found " << drv_udis[d] << ": "
- << media.asString() << std::endl;
- if( supportingDVD && supportsDVD)
- {
- detected.push_front(media);
- }
- else
- {
- detected.push_back(media);
- }
- }
+ // In case we need it someday:
+ //const char * mountpath = ::udev_device_get_property_value( device, "FSTAB_DIR" );
+
+ PathInfo devnode( devnodePtr );
+ if ( devnode.isBlk() )
+ {
+ MediaSource media( "cdrom", devnode.path().asString(), devnode.major(), devnode.minor() );
+ DBG << "Found (udev): " << media << std::endl;
+ detected.push_back( media );
}
}
- catch(const zypp::target::hal::HalException &e)
- {
- ZYPP_CAUGHT(e);
- }
-#else // NO_HAL
-#warning Poor CDROM devices detection without HAL
- WAR << "Cdrom drive detection without HAL! " << std::endl;
- PathInfo dvdinfo( "/dev/dvd" );
- PathInfo cdrinfo( "/dev/cdrom" );
- if ( dvdinfo.isBlk() )
- {
- MediaSource media( "cdrom", dvdinfo.path().asString(), dvdinfo.major(), dvdinfo.minor() );
- DBG << "Found (NO_HAL): " << media << std::endl;
- detected.push_back( media );
- }
- if ( cdrinfo.isBlk()
- && ! ( cdrinfo.major() == dvdinfo.major() && cdrinfo.minor() == dvdinfo.minor() ) )
- {
- MediaSource media( "cdrom", cdrinfo.path().asString(), cdrinfo.major(), cdrinfo.minor() );
- DBG << "Found (NO_HAL): " << media << std::endl;
- detected.push_back( media );
- }
-#endif
return detected;
}
break;
}
-#if REUSE_FOREIGN_MOUNTS > 0
{
MediaManager manager;
MountEntries entries( manager.getMountEntries());
{
AttachPointRef ap( new AttachPoint(e->dir, false));
AttachedMedia am( media, ap);
- //
- // 1 = automounted only, 2 == all
- //
-#if REUSE_FOREIGN_MOUNTS == 1
- if( isAutoMountedMedia(am))
-#endif
{
DBG << "Using a system mounted media "
<< media->name
if( mountsucceeded)
break;
}
-#endif // REUSE_FOREIGN_MOUNTS
// close tray
closeTray( it->name );
ZYPP_CAUGHT(excpt_r);
if (!ejectDev.empty())
{
-#if FORCE_RELEASE_FOREIGN > 0
- /* 1 = automounted only, 2 = all */
- forceRelaseAllMedia(false, FORCE_RELEASE_FOREIGN == 1);
-#endif
+ forceRelaseAllMedia(false);
if(openTray( ejectDev ))
return;
}
// eject device
if (!ejectDev.empty())
{
-#if FORCE_RELEASE_FOREIGN > 0
- /* 1 = automounted only, 2 = all */
- forceRelaseAllMedia(false, FORCE_RELEASE_FOREIGN == 1);
-#endif
+ forceRelaseAllMedia(false);
if( !openTray( ejectDev ))
{
#if REPORT_EJECT_ERRORS
AttachedMedia ret( findAttachedMedia( media));
if( !ret.mediaSource)
{
-#if FORCE_RELEASE_FOREIGN > 0
- /* 1 = automounted only, 2 = all */
- forceRelaseAllMedia(media, false, FORCE_RELEASE_FOREIGN == 1);
-#endif
+ forceRelaseAllMedia(media, false);
if ( openTray( it->name ) )
{
ejected = true;
}
}
- bool MediaCD::isAutoMountedMedia(const AttachedMedia &media)
- {
- bool is_automounted = false;
- if( media.mediaSource && !media.mediaSource->name.empty())
- {
-#ifndef NO_HAL
- using namespace zypp::target::hal;
- try
- {
- HalContext hal(true);
-
- HalVolume vol = hal.getVolumeFromDeviceFile(media.mediaSource->name);
- if( vol)
- {
- std::string udi = vol.getUDI();
- std::string key;
- std::string mnt;
-
- try
- {
- key = "info.hal_mount.created_mount_point";
- mnt = hal.getDevicePropertyString(udi, key);
-
- if(media.attachPoint->path == mnt)
- is_automounted = true;
- }
- catch(const HalException &e1)
- {
- ZYPP_CAUGHT(e1);
-
- try
- {
- key = "volume.mount_point";
- mnt = hal.getDevicePropertyString(udi, key);
-
- if(media.attachPoint->path == mnt)
- is_automounted = true;
- }
- catch(const HalException &e2)
- {
- ZYPP_CAUGHT(e2);
- }
- }
- }
- }
- catch(const HalException &e)
- {
- ZYPP_CAUGHT(e);
- }
-#else // NO_HAL
-#warning Can not detect automounted media without HAL
- INT << "Can not detect automounted media without HAL!" << endl;
- // ma@: This codepath is probably unused due to 'REUSE_FOREIGN_MOUNTS == 2'
- // Maybe we should cleanup all this automount-specail-handling.
-#endif
- }
- DBG << "Media " << media.mediaSource->asString()
- << " attached on " << media.attachPoint->path
- << " is" << (is_automounted ? "" : " not")
- << " automounted" << std::endl;
- return is_automounted;
- }
-
///////////////////////////////////////////////////////////////////
//
// METHOD NAME : MediaCD::isAttached