From 9d76cb942d54c5e8edec59d90644326219b1c4a0 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Mon, 26 Aug 2013 10:32:41 -0500 Subject: Disable suspend/hibernate if $HOME is a network file system This resolves Bug 1615 --- tdecore/tdehw/tderootsystemdevice.cpp | 32 +++++++++++++++++++++ tdecore/tdehw/tdestoragedevice.cpp | 54 +++++++++++++++++++++++++++++++++++ tdecore/tdehw/tdestoragedevice.h | 7 +++++ 3 files changed, 93 insertions(+) (limited to 'tdecore') diff --git a/tdecore/tdehw/tderootsystemdevice.cpp b/tdecore/tdehw/tderootsystemdevice.cpp index 86a92340c..3f12b4d5a 100644 --- a/tdecore/tdehw/tderootsystemdevice.cpp +++ b/tdecore/tdehw/tderootsystemdevice.cpp @@ -18,6 +18,7 @@ */ #include "tderootsystemdevice.h" +#include "tdestoragedevice.h" #include @@ -27,6 +28,7 @@ #include "tdeglobal.h" #include "tdeconfig.h" #include "tdeapplication.h" +#include "kstandarddirs.h" #include "config.h" @@ -38,6 +40,16 @@ #include #endif // defined(WITH_TDEHWLIB_DAEMONS) || defined(WITH_UPOWER) || defined(WITH_DEVKITPOWER) || defined(WITH_HAL) || defined(WITH_CONSOLEKIT) +bool isNetworkFileSystem(TQString fileSystemType) { + if ((fileSystemType.startsWith("nfs")) + || (fileSystemType == "cifs") + ) { + return TRUE; + } + + return FALSE; +} + TDERootSystemDevice::TDERootSystemDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) : TDEGenericDevice(dt, dn) { m_hibernationSpace = -1; } @@ -97,6 +109,12 @@ bool TDERootSystemDevice::canSetHibernationMethod() { } bool TDERootSystemDevice::canStandby() { + // Network file systems mounted on $HOME typically cause nasty suspend/resume failures + // See Bug 1615 for details + if (isNetworkFileSystem(TDEStorageDevice::determineFileSystemType(TDEGlobal::dirs()->localtdedir()))) { + return FALSE; + } + TQString statenode = "/sys/power/state"; int rval = access (statenode.ascii(), W_OK); if (rval == 0) { @@ -125,9 +143,17 @@ bool TDERootSystemDevice::canStandby() { } } #endif // WITH_TDEHWLIB_DAEMONS + + return FALSE; } bool TDERootSystemDevice::canSuspend() { + // Network file systems mounted on $HOME typically cause nasty suspend/resume failures + // See Bug 1615 for details + if (isNetworkFileSystem(TDEStorageDevice::determineFileSystemType(TDEGlobal::dirs()->localtdedir()))) { + return FALSE; + } + TQString statenode = "/sys/power/state"; int rval = access (statenode.ascii(), W_OK); if (rval == 0) { @@ -223,6 +249,12 @@ bool TDERootSystemDevice::canSuspend() { } bool TDERootSystemDevice::canHibernate() { + // Network file systems mounted on $HOME typically cause nasty suspend/resume failures + // See Bug 1615 for details + if (isNetworkFileSystem(TDEStorageDevice::determineFileSystemType(TDEGlobal::dirs()->localtdedir()))) { + return FALSE; + } + TQString statenode = "/sys/power/state"; int rval = access (statenode.ascii(), W_OK); if (rval == 0) { diff --git a/tdecore/tdehw/tdestoragedevice.cpp b/tdecore/tdehw/tdestoragedevice.cpp index f13146b00..3824f488e 100644 --- a/tdecore/tdehw/tdestoragedevice.cpp +++ b/tdecore/tdehw/tdestoragedevice.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -769,4 +770,57 @@ bool TDEStorageDevice::unmountDevice(TQString* errRet, int* retcode) { return false; } +TQString TDEStorageDevice::determineFileSystemType(TQString path) { + TQStringList mountTable; + TQString prevPath = path; + dev_t prevDev = 0; + int pos; + struct stat directory_info; + if (path.startsWith("/")) { + stat(path.ascii(), &directory_info); + prevDev = directory_info.st_dev; + // Walk the directory tree up to the root, checking for any change in st_dev + // If a change is found, the previous value of path is the mount point itself + while (path != "/") { + pos = path.findRev("/", -1, TRUE); + if (pos < 0) { + break; + } + path = path.mid(0, pos); + if (path == "") { + path = "/"; + } + stat(path.ascii(), &directory_info); + if (directory_info.st_dev != prevDev) { + break; + } + prevPath = path; + prevDev = directory_info.st_dev; + } + } + + // Read in mount table + mountTable.clear(); + TQFile file( "/proc/mounts" ); + if ( file.open( IO_ReadOnly ) ) { + TQTextStream stream( &file ); + while ( !stream.atEnd() ) { + mountTable.append(stream.readLine()); + } + file.close(); + } + + // Parse mount table + TQStringList::Iterator it; + for ( it = mountTable.begin(); it != mountTable.end(); ++it ) { + TQStringList mountInfo = TQStringList::split(" ", (*it), true); + if ((*mountInfo.at(1)) == prevPath) { + return (*mountInfo.at(2)); + } + } + + // Unknown file system type + return TQString::null; +} + #include "tdestoragedevice.moc" diff --git a/tdecore/tdehw/tdestoragedevice.h b/tdecore/tdehw/tdestoragedevice.h index 6e6270f9e..1199510a4 100644 --- a/tdecore/tdehw/tdestoragedevice.h +++ b/tdecore/tdehw/tdestoragedevice.h @@ -290,6 +290,13 @@ class TDECORE_EXPORT TDEStorageDevice : public TDEGenericDevice */ bool ejectDrive(); + /** + * @param path Full path to arbitrary file or directory + * @return TQString with type of file system containing the given file, + * or TQString::null if file system type unknown + */ + static TQString determineFileSystemType(TQString path); + protected: /** * @param a TQString with the disk or partition label, if any -- cgit v1.2.1