OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * $Id: _psutil_linux.c 1142 2011-10-05 18:45:49Z g.rodola $ |
| 3 * |
| 4 * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved. |
| 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. |
| 7 * |
| 8 * Linux-specific functions. |
| 9 */ |
| 10 |
| 11 #include <Python.h> |
| 12 #include <errno.h> |
| 13 #include <stdlib.h> |
| 14 #include <mntent.h> |
| 15 #include <sys/syscall.h> |
| 16 #include <linux/unistd.h> |
| 17 |
| 18 #include "_psutil_linux.h" |
| 19 |
| 20 |
| 21 #define HAS_IOPRIO defined(__NR_ioprio_get) && defined(__NR_ioprio_set) |
| 22 |
| 23 #if HAS_IOPRIO |
| 24 enum { |
| 25 IOPRIO_WHO_PROCESS = 1, |
| 26 }; |
| 27 |
| 28 static inline int |
| 29 ioprio_get(int which, int who) |
| 30 { |
| 31 return syscall(__NR_ioprio_get, which, who); |
| 32 } |
| 33 |
| 34 static inline int |
| 35 ioprio_set(int which, int who, int ioprio) |
| 36 { |
| 37 return syscall(__NR_ioprio_set, which, who, ioprio); |
| 38 } |
| 39 |
| 40 #define IOPRIO_CLASS_SHIFT 13 |
| 41 #define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1) |
| 42 |
| 43 #define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT) |
| 44 #define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK) |
| 45 #define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data) |
| 46 |
| 47 |
| 48 /* |
| 49 * Return a (ioclass, iodata) Python tuple representing process I/O priority. |
| 50 */ |
| 51 static PyObject* |
| 52 linux_ioprio_get(PyObject* self, PyObject* args) |
| 53 { |
| 54 long pid; |
| 55 int ioprio, ioclass, iodata; |
| 56 if (! PyArg_ParseTuple(args, "l", &pid)) { |
| 57 return NULL; |
| 58 } |
| 59 ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid); |
| 60 if (ioprio == -1) { |
| 61 return PyErr_SetFromErrno(PyExc_OSError); |
| 62 } |
| 63 ioclass = IOPRIO_PRIO_CLASS(ioprio); |
| 64 iodata = IOPRIO_PRIO_DATA(ioprio); |
| 65 return Py_BuildValue("ii", ioclass, iodata); |
| 66 } |
| 67 |
| 68 |
| 69 /* |
| 70 * A wrapper around ioprio_set(); sets process I/O priority. |
| 71 * ioclass can be either IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE |
| 72 * or 0. iodata goes from 0 to 7 depending on ioclass specified. |
| 73 */ |
| 74 static PyObject* |
| 75 linux_ioprio_set(PyObject* self, PyObject* args) |
| 76 { |
| 77 long pid; |
| 78 int ioprio, ioclass, iodata; |
| 79 int retval; |
| 80 |
| 81 if (! PyArg_ParseTuple(args, "lii", &pid, &ioclass, &iodata)) { |
| 82 return NULL; |
| 83 } |
| 84 ioprio = IOPRIO_PRIO_VALUE(ioclass, iodata); |
| 85 retval = ioprio_set(IOPRIO_WHO_PROCESS, pid, ioprio); |
| 86 if (retval == -1) { |
| 87 return PyErr_SetFromErrno(PyExc_OSError); |
| 88 } |
| 89 Py_INCREF(Py_None); |
| 90 return Py_None; |
| 91 } |
| 92 #endif |
| 93 |
| 94 |
| 95 /* |
| 96 * Return disk mounted partitions as a list of tuples including device, |
| 97 * mount point and filesystem type |
| 98 */ |
| 99 static PyObject* |
| 100 get_disk_partitions(PyObject* self, PyObject* args) |
| 101 { |
| 102 FILE *file; |
| 103 struct mntent *entry; |
| 104 PyObject* py_retlist = PyList_New(0); |
| 105 PyObject* py_tuple; |
| 106 |
| 107 // MOUNTED constant comes from mntent.h and it's == '/etc/mtab' |
| 108 Py_BEGIN_ALLOW_THREADS |
| 109 file = setmntent(MOUNTED, "r"); |
| 110 Py_END_ALLOW_THREADS |
| 111 if ((file == 0) || (file == NULL)) { |
| 112 return PyErr_SetFromErrno(PyExc_OSError); |
| 113 } |
| 114 |
| 115 while ((entry = getmntent(file))) { |
| 116 if (entry == NULL) { |
| 117 endmntent(file); |
| 118 return PyErr_Format(PyExc_RuntimeError, "getmntent() failed"); |
| 119 } |
| 120 py_tuple = Py_BuildValue("(sss)", entry->mnt_fsname, // device |
| 121 entry->mnt_dir, // mount point |
| 122 entry->mnt_type); // fs type |
| 123 PyList_Append(py_retlist, py_tuple); |
| 124 Py_XDECREF(py_tuple); |
| 125 } |
| 126 |
| 127 endmntent(file); |
| 128 return py_retlist; |
| 129 } |
| 130 |
| 131 |
| 132 /* |
| 133 * Define the psutil C module methods and initialize the module. |
| 134 */ |
| 135 static PyMethodDef |
| 136 PsutilMethods[] = |
| 137 { |
| 138 #if HAS_IOPRIO |
| 139 {"ioprio_get", linux_ioprio_get, METH_VARARGS, |
| 140 "Get process I/O priority"}, |
| 141 {"ioprio_set", linux_ioprio_set, METH_VARARGS, |
| 142 "Set process I/O priority"}, |
| 143 #endif |
| 144 {"get_disk_partitions", get_disk_partitions, METH_VARARGS, |
| 145 "Return disk mounted partitions as a list of tuples including " |
| 146 "device, mount point and filesystem type"}, |
| 147 |
| 148 {NULL, NULL, 0, NULL} |
| 149 }; |
| 150 |
| 151 struct module_state { |
| 152 PyObject *error; |
| 153 }; |
| 154 |
| 155 #if PY_MAJOR_VERSION >= 3 |
| 156 #define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) |
| 157 #else |
| 158 #define GETSTATE(m) (&_state) |
| 159 #endif |
| 160 |
| 161 #if PY_MAJOR_VERSION >= 3 |
| 162 |
| 163 static int |
| 164 psutil_linux_traverse(PyObject *m, visitproc visit, void *arg) { |
| 165 Py_VISIT(GETSTATE(m)->error); |
| 166 return 0; |
| 167 } |
| 168 |
| 169 static int |
| 170 psutil_linux_clear(PyObject *m) { |
| 171 Py_CLEAR(GETSTATE(m)->error); |
| 172 return 0; |
| 173 } |
| 174 |
| 175 static struct PyModuleDef |
| 176 moduledef = { |
| 177 PyModuleDef_HEAD_INIT, |
| 178 "psutil_linux", |
| 179 NULL, |
| 180 sizeof(struct module_state), |
| 181 PsutilMethods, |
| 182 NULL, |
| 183 psutil_linux_traverse, |
| 184 psutil_linux_clear, |
| 185 NULL |
| 186 }; |
| 187 |
| 188 #define INITERROR return NULL |
| 189 |
| 190 PyObject * |
| 191 PyInit__psutil_linux(void) |
| 192 |
| 193 #else |
| 194 #define INITERROR return |
| 195 |
| 196 void init_psutil_linux(void) |
| 197 #endif |
| 198 { |
| 199 #if PY_MAJOR_VERSION >= 3 |
| 200 PyObject *module = PyModule_Create(&moduledef); |
| 201 #else |
| 202 PyObject *module = Py_InitModule("_psutil_linux", PsutilMethods); |
| 203 #endif |
| 204 if (module == NULL) { |
| 205 INITERROR; |
| 206 } |
| 207 #if PY_MAJOR_VERSION >= 3 |
| 208 return module; |
| 209 #endif |
| 210 } |
| 211 |
OLD | NEW |