From fbece8e45991e8cc070bfd5e9efcd4974227abcd Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Fri, 19 Oct 2018 14:27:56 +0200 Subject: [PATCH] fix #1307: [Linux] disk_partitions() does not honour PROCFS_PATH --- HISTORY.rst | 1 + psutil/_pslinux.py | 11 +++++++++-- psutil/_psutil_linux.c | 9 ++++++--- psutil/tests/test_connections.py | 1 + psutil/tests/test_linux.py | 12 ++++++++++++ psutil/tests/test_system.py | 6 +----- 6 files changed, 30 insertions(+), 10 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 448370948..a02b8e2c0 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -22,6 +22,7 @@ XXXX-XX-XX not accurate. - 1294_: [Windows] psutil.Process().connections() may sometimes fail with intermittent 0xC0000001. (patch by Sylvain Duchesne) +- 1307_: [Linux] disk_partitions() does not honour PROCFS_PATH. - 1320_: [AIX] system CPU times (psutil.cpu_times()) were being reported with ticks unit as opposed to seconds. (patch by Jaime Fullaondo) - 1332_: [OSX] psutil debug messages are erroneously printed all the time. diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index 236934fc9..82e321899 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -1140,7 +1140,8 @@ def read_sysfs(): def disk_partitions(all=False): """Return mounted disk partitions as a list of namedtuples.""" fstypes = set() - with open_text("%s/filesystems" % get_procfs_path()) as f: + procfs_path = get_procfs_path() + with open_text("%s/filesystems" % procfs_path) as f: for line in f: line = line.strip() if not line.startswith("nodev"): @@ -1151,8 +1152,14 @@ def disk_partitions(all=False): if fstype == "zfs": fstypes.add("zfs") + # See: https://github.com/giampaolo/psutil/issues/1307 + if procfs_path == "/proc": + mtab_path = os.path.realpath("/etc/mtab") + else: + mtab_path = os.path.realpath("%s/self/mounts" % procfs_path) + retlist = [] - partitions = cext.disk_partitions() + partitions = cext.disk_partitions(mtab_path) for partition in partitions: device, mountpoint, fstype, opts = partition if device == 'none': diff --git a/psutil/_psutil_linux.c b/psutil/_psutil_linux.c index d1f0d1455..bd27b5f9c 100644 --- a/psutil/_psutil_linux.c +++ b/psutil/_psutil_linux.c @@ -195,6 +195,7 @@ static PyObject * psutil_disk_partitions(PyObject *self, PyObject *args) { FILE *file = NULL; struct mntent *entry; + const char *mtab_path; PyObject *py_dev = NULL; PyObject *py_mountp = NULL; PyObject *py_tuple = NULL; @@ -203,12 +204,14 @@ psutil_disk_partitions(PyObject *self, PyObject *args) { if (py_retlist == NULL) return NULL; - // MOUNTED constant comes from mntent.h and it's == '/etc/mtab' + if (!PyArg_ParseTuple(args, "s", &mtab_path)) + return NULL; + Py_BEGIN_ALLOW_THREADS - file = setmntent(MOUNTED, "r"); + file = setmntent(mtab_path, "r"); Py_END_ALLOW_THREADS if ((file == 0) || (file == NULL)) { - PyErr_SetFromErrnoWithFilename(PyExc_OSError, MOUNTED); + PyErr_SetFromErrnoWithFilename(PyExc_OSError, mtab_path); goto error; } diff --git a/psutil/tests/test_connections.py b/psutil/tests/test_connections.py index cba835e14..7f59a74cb 100755 --- a/psutil/tests/test_connections.py +++ b/psutil/tests/test_connections.py @@ -53,6 +53,7 @@ class Base(object): def setUp(self): + safe_rmpath(TESTFN) if not NETBSD: # NetBSD opens a UNIX socket to /var/log/run. cons = thisproc.connections(kind='all') diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py index 115a6af8a..4b72f7257 100755 --- a/psutil/tests/test_linux.py +++ b/psutil/tests/test_linux.py @@ -1011,6 +1011,18 @@ def test_disk_partitions_mocked(self): assert ret self.assertEqual(ret[0].fstype, 'zfs') + def test_disk_partitions_procfs(self): + # See: https://github.com/giampaolo/psutil/issues/1307 + try: + with mock.patch('os.path.realpath', + return_value='/non/existent') as m: + with self.assertRaises(OSError) as cm: + psutil.disk_partitions() + assert m.called + self.assertEqual(cm.exception.errno, errno.ENOENT) + finally: + psutil.PROCFS_PATH = "/proc" + def test_disk_io_counters_kernel_2_4_mocked(self): # Tests /proc/diskstats parsing format for 2.4 kernels, see: # https://github.com/giampaolo/psutil/issues/767 diff --git a/psutil/tests/test_system.py b/psutil/tests/test_system.py index 8b07caff6..7cc678f05 100755 --- a/psutil/tests/test_system.py +++ b/psutil/tests/test_system.py @@ -522,11 +522,7 @@ def test_disk_partitions(self): if err.errno not in (errno.EPERM, errno.EACCES): raise else: - if SUNOS or TRAVIS: - # on solaris apparently mount points can also be files - assert os.path.exists(disk.mountpoint), disk - else: - assert os.path.isdir(disk.mountpoint), disk + assert os.path.exists(disk.mountpoint), disk self.assertIsInstance(disk.fstype, str) self.assertIsInstance(disk.opts, str)