summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-04-01 18:58:24 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-04-01 18:58:24 -0500
commit4e0646cb8c0d1c4888f99f5128dbe439ea70067a (patch)
treec8abcf75fd8067ecbbc0ecd40ea219671f01cda2
parentc7e94c427aa0d4e44e1a1ba779935953efa0df6d (diff)
downloadtdelibs-4e0646cb.tar.gz
tdelibs-4e0646cb.zip
Fix a number of bugs in the TDE hardware library and stabilize device mapper device detection
-rw-r--r--tdecore/tdehardwaredevices.cpp112
-rw-r--r--tdecore/tdehardwaredevices.h5
2 files changed, 94 insertions, 23 deletions
diff --git a/tdecore/tdehardwaredevices.cpp b/tdecore/tdehardwaredevices.cpp
index b8d8d7e6f..e1337d8e1 100644
--- a/tdecore/tdehardwaredevices.cpp
+++ b/tdecore/tdehardwaredevices.cpp
@@ -178,7 +178,7 @@ TQStringList &TDEStorageDevice::holdingDevices() {
}
void TDEStorageDevice::setHoldingDevices(TQStringList hd) {
- m_slaveDevices = hd;
+ m_holdingDevices = hd;
}
TQStringList &TDEStorageDevice::slaveDevices() {
@@ -258,6 +258,10 @@ TQString TDEStorageDevice::mountPath() {
// The Device Mapper throws a monkey wrench into this
// It likes to advertise mounts as /dev/mapper/<something>,
// where <something> is listed in <system path>/dm/name
+
+ // First, ensure that all device information (mainly holders/slaves) is accurate
+ KGlobal::hardwareDevices()->rescanDeviceInformation(this);
+
TQString dmnodename = systemPath();
dmnodename.append("/dm/name");
TQFile namefile( dmnodename );
@@ -279,7 +283,9 @@ TQString TDEStorageDevice::mountPath() {
while ( !stream.atEnd() ) {
line = stream.readLine();
TQStringList mountInfo = TQStringList::split(" ", line, true);
- if ((*mountInfo.at(0) == deviceNode()) || (*mountInfo.at(0) == dmaltname)) {
+ TQString testNode = *mountInfo.at(0);
+ // Check for match
+ if ((testNode == deviceNode()) || (testNode == dmaltname)) {
return *mountInfo.at(1);
}
lines += line;
@@ -289,7 +295,7 @@ TQString TDEStorageDevice::mountPath() {
// While this device is not directly mounted, it could concievably be mounted via the Device Mapper
// If so, try to retrieve the mount path...
- TQStringList slaveDeviceList = slaveDevices();
+ TQStringList slaveDeviceList = holdingDevices();
for ( TQStringList::Iterator slavedevit = slaveDeviceList.begin(); slavedevit != slaveDeviceList.end(); ++slavedevit ) {
// Try to locate this device path in the TDE device tree
TDEHardwareDevices *hwdevices = KGlobal::hardwareDevices();
@@ -330,16 +336,16 @@ TQString TDEStorageDevice::mountDevice(TQString mediaName, TQString mountOptions
char buffer[8092];
pmount_output = fgets(buffer, sizeof(buffer), exepipe);
*retcode = pclose(exepipe);
- if (*retcode == 0) {
- ret = mountPath();
- }
- else {
- if (errRet) {
- *errRet = pmount_output;
- }
+ if (errRet) {
+ *errRet = pmount_output;
}
}
+ // Update internal mount data
+ KGlobal::hardwareDevices()->processModifiedMounts();
+
+ ret = mountPath();
+
return ret;
}
@@ -377,16 +383,16 @@ TQString TDEStorageDevice::mountEncryptedDevice(TQString passphrase, TQString me
char buffer[8092];
pmount_output = fgets(buffer, sizeof(buffer), exepipe);
*retcode = pclose(exepipe);
- if (*retcode == 0) {
- ret = mountPath();
- }
- else {
- if (errRet) {
- *errRet = pmount_output;
- }
+ if (errRet) {
+ *errRet = pmount_output;
}
}
+ // Update internal mount data
+ KGlobal::hardwareDevices()->processModifiedMounts();
+
+ ret = mountPath();
+
return ret;
}
@@ -419,6 +425,9 @@ bool TDEStorageDevice::unmountDevice(TQString* errRet, int* retcode) {
}
}
+ // Update internal mount data
+ KGlobal::hardwareDevices()->processModifiedMounts();
+
return false;
}
@@ -471,6 +480,13 @@ TDEHardwareDevices::~TDEHardwareDevices() {
udev_unref(m_udevStruct);
}
+void TDEHardwareDevices::rescanDeviceInformation(TDEGenericDevice* hwdevice) {
+ struct udev_device *dev;
+ dev = udev_device_new_from_syspath(m_udevStruct, hwdevice->systemPath().ascii());
+ classifyUnknownDevice(dev, hwdevice);
+ udev_device_unref(dev);
+}
+
TDEGenericDevice* TDEHardwareDevices::findBySystemPath(TQString syspath) {
TDEGenericDevice *hwdevice;
for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
@@ -536,7 +552,24 @@ void TDEHardwareDevices::processHotPluggedHardware() {
for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
if (hwdevice->systemPath() == systempath) {
emit hardwareRemoved(hwdevice);
- m_deviceList.remove(hwdevice);
+
+ // If the device is a storage device and has a slave, update it as well
+ if (hwdevice->type() == TDEGenericDeviceType::Disk) {
+ TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
+ TQStringList slavedevices = sdevice->slaveDevices();
+ m_deviceList.remove(hwdevice);
+ for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
+ TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
+ if (slavedevice) {
+ rescanDeviceInformation(slavedevice);
+ emit hardwareUpdated(slavedevice);
+ }
+ }
+ }
+ else {
+ m_deviceList.remove(hwdevice);
+ }
+
break;
}
}
@@ -547,8 +580,20 @@ void TDEHardwareDevices::processHotPluggedHardware() {
TDEGenericDevice *hwdevice;
for (hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next()) {
if (hwdevice->systemPath() == systempath) {
- classifyUnknownDevice(dev, hwdevice);
-// emit hardwareUpdated(hwdevice); // FIXME certain devices (***cough U3 system fake CD cough*** spam this quite badly, locking up anything monitoring hardwareUpdated()
+ // HACK
+ // I am lucky enough to have a Flash drive that spams udev continually with device change events
+ // I imagine I am not the only one, so here is a section in which specific devices can be blacklisted!
+ bool blacklisted = false;
+
+ // For "U3 System" fake CD
+ if ((TQString(udev_device_get_property_value(dev, "ID_VENDOR_ID")) == "08ec") && (TQString(udev_device_get_property_value(dev, "ID_MODEL_ID")) == "0020") && (TQString(udev_device_get_property_value(dev, "ID_TYPE")) == "cd")); {
+ blacklisted = true;
+ }
+
+ if (!blacklisted) {
+ classifyUnknownDevice(dev, hwdevice);
+ emit hardwareUpdated(hwdevice);
+ }
break;
}
}
@@ -557,7 +602,6 @@ void TDEHardwareDevices::processHotPluggedHardware() {
}
void TDEHardwareDevices::processModifiedMounts() {
- // FIXME
// Detect what changed between the old mount table and the new one,
// and emit appropriate events
@@ -602,7 +646,7 @@ void TDEHardwareDevices::processModifiedMounts() {
if (hwdevice->type() == TDEGenericDeviceType::Disk) {
TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
TQStringList slavedevices = sdevice->slaveDevices();
- for ( TQStringList::Iterator slaveit = addedEntries.begin(); slaveit != addedEntries.end(); ++slaveit ) {
+ for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
if (slavedevice) {
emit hardwareUpdated(slavedevice);
@@ -621,7 +665,7 @@ void TDEHardwareDevices::processModifiedMounts() {
if (hwdevice->type() == TDEGenericDeviceType::Disk) {
TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
TQStringList slavedevices = sdevice->slaveDevices();
- for ( TQStringList::Iterator slaveit = addedEntries.begin(); slaveit != addedEntries.end(); ++slaveit ) {
+ for ( TQStringList::Iterator slaveit = slavedevices.begin(); slaveit != slavedevices.end(); ++slaveit ) {
TDEGenericDevice* slavedevice = findBySystemPath(*slaveit);
if (slavedevice) {
emit hardwareUpdated(slavedevice);
@@ -701,6 +745,12 @@ TDEDiskDeviceType::TDEDiskDeviceType classifyDiskType(udev_device* dev, const TQ
disktype = disktype | TDEDiskDeviceType::HDD;
}
+ // Certain combinations of media flags should never be set at the same time as they don't make sense
+ // This block is needed as udev is more than happy to provide inconsistent data to us
+ if ((disktype & TDEDiskDeviceType::Zip) || (disktype & TDEDiskDeviceType::Floppy) || (disktype & TDEDiskDeviceType::Jaz)) {
+ disktype = disktype & ~TDEDiskDeviceType::HDD;
+ }
+
if (disktypestring.upper() == "CD") {
if (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA")) == "1") {
disktype = disktype | TDEDiskDeviceType::CDROM;
@@ -867,6 +917,22 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD
sdevice->setMediaInserted(!(TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA")) == "0"));
}
+ if (disktype & TDEDiskDeviceType::Zip) {
+ // A Zip drive does not advertise its status via udev, but it can be guessed from the size parameter
+ TQString zipnodename = systempath;
+ zipnodename.append("/size");
+ TQFile namefile( zipnodename );
+ TQString zipsize;
+ if ( namefile.open( IO_ReadOnly ) ) {
+ TQTextStream stream( &namefile );
+ zipsize = stream.readLine();
+ namefile.close();
+ }
+ if (!zipsize.isNull()) {
+ sdevice->setMediaInserted((zipsize.toInt() != 0));
+ }
+ }
+
if (removable) {
diskstatus = diskstatus | TDEDiskDeviceStatus::Removable;
}
diff --git a/tdecore/tdehardwaredevices.h b/tdecore/tdehardwaredevices.h
index 0da239663..c6cf43cac 100644
--- a/tdecore/tdehardwaredevices.h
+++ b/tdecore/tdehardwaredevices.h
@@ -494,6 +494,9 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject
void processModifiedMounts();
private:
+ void rescanDeviceInformation(TDEGenericDevice* hwdevice);
+
+ private:
TDEGenericDevice *classifyUnknownDevice(udev_device* dev, TDEGenericDevice* existingdevice=0);
struct udev *m_udevStruct;
@@ -505,6 +508,8 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject
TQSocketNotifier* m_mountScanNotifier;
TQStringList m_mountTable;
+
+ friend class TDEStorageDevice;
};
#endif \ No newline at end of file