Skip to content

Commit

Permalink
fix #1307: [Linux] disk_partitions() does not honour PROCFS_PATH
Browse files Browse the repository at this point in the history
  • Loading branch information
giampaolo committed Oct 19, 2018
1 parent 6db8d2e commit fbece8e
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 10 deletions.
1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
11 changes: 9 additions & 2 deletions psutil/_pslinux.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"):
Expand All @@ -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':
Expand Down
9 changes: 6 additions & 3 deletions psutil/_psutil_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down
1 change: 1 addition & 0 deletions psutil/tests/test_connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down
12 changes: 12 additions & 0 deletions psutil/tests/test_linux.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 1 addition & 5 deletions psutil/tests/test_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit fbece8e

Please sign in to comment.