From 9f394c7a94c55f7d5c26ee6486996c67978b8e15 Mon Sep 17 00:00:00 2001 From: Arnon Yaari Date: Sat, 5 Sep 2015 19:44:24 +0300 Subject: [PATCH 1/4] Fix #517 by testing ksp->ks_name is a network interface instead of testing ksp->ks_module is 'link' --- psutil/_psutil_sunos.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/psutil/_psutil_sunos.c b/psutil/_psutil_sunos.c index aa6c702db..f0282e82f 100644 --- a/psutil/_psutil_sunos.c +++ b/psutil/_psutil_sunos.c @@ -675,6 +675,9 @@ psutil_net_io_counters(PyObject *self, PyObject *args) { kstat_ctl_t *kc = NULL; kstat_t *ksp; kstat_named_t *rbytes, *wbytes, *rpkts, *wpkts, *ierrs, *oerrs; + int ret; + int sock = -1; + struct lifreq ifr; PyObject *py_retdict = PyDict_New(); PyObject *py_ifc_info = NULL; @@ -685,25 +688,30 @@ psutil_net_io_counters(PyObject *self, PyObject *args) { if (kc == NULL) goto error; + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == -1) + goto error; + ksp = kc->kc_chain; while (ksp != NULL) { if (ksp->ks_type != KSTAT_TYPE_NAMED) goto next; if (strcmp(ksp->ks_class, "net") != 0) goto next; - /* - // XXX "lo" (localhost) interface makes kstat_data_lookup() fail - // (maybe because "ifconfig -a" says it's a virtual interface?). - if ((strcmp(ksp->ks_module, "link") != 0) && - (strcmp(ksp->ks_module, "lo") != 0)) { - goto skip; - */ - if ((strcmp(ksp->ks_module, "link") != 0)) + // skip 'lo' (localhost) because it doesn't have the statistics we need + // and it makes kstat_data_lookup() fail + if (strcmp(ksp->ks_module, "lo") == 0) + goto next; + + // check if this is a network interface by sending a ioctl + strncpy(ifr.lifr_name, ksp->ks_name, sizeof(ifr.lifr_name)); + ret = ioctl(sock, SIOCGLIFFLAGS, &ifr); + if (ret == -1) goto next; if (kstat_read(kc, ksp, NULL) == -1) { errno = 0; - continue; + goto next; } rbytes = (kstat_named_t *)kstat_data_lookup(ksp, "rbytes"); @@ -752,6 +760,7 @@ psutil_net_io_counters(PyObject *self, PyObject *args) { } kstat_close(kc); + close(sock); return py_retdict; error: @@ -759,6 +768,9 @@ psutil_net_io_counters(PyObject *self, PyObject *args) { Py_DECREF(py_retdict); if (kc != NULL) kstat_close(kc); + if (sock != -1) { + close(sock); + } return NULL; } @@ -1138,7 +1150,7 @@ psutil_net_if_stats(PyObject* self, PyObject* args) { kstat_t *ksp; kstat_named_t *knp; int ret; - int sock = 0; + int sock = -1; int duplex; int speed; @@ -1226,7 +1238,7 @@ psutil_net_if_stats(PyObject* self, PyObject* args) { Py_XDECREF(py_is_up); Py_XDECREF(py_ifc_info); Py_DECREF(py_retdict); - if (sock != 0) + if (sock != -1) close(sock); if (kc != NULL) kstat_close(kc); From 9fc4b0e7612306b22189f9ec94d31001b9c60244 Mon Sep 17 00:00:00 2001 From: Arnon Yaari Date: Sun, 6 Sep 2015 11:30:40 +0300 Subject: [PATCH 2/4] #517 The data type retrurned from kstat is interface dependent and not system dependent _INT64_TYPE may be defined but kstat may still return the IO counters in 32-bit types. In addition, on SunOS, sizeof(long)==sizeof(long long)==8 so using 'k' and 'K' means the same, and we need to ue 'I' for unsigned 32 bit integers. --- psutil/_psutil_sunos.c | 46 ++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/psutil/_psutil_sunos.c b/psutil/_psutil_sunos.c index f0282e82f..9f1f5e59a 100644 --- a/psutil/_psutil_sunos.c +++ b/psutil/_psutil_sunos.c @@ -728,26 +728,32 @@ psutil_net_io_counters(PyObject *self, PyObject *args) { goto error; } -#if defined(_INT64_TYPE) - py_ifc_info = Py_BuildValue("(KKKKkkii)", - wbytes->value.ui64, - rbytes->value.ui64, - wpkts->value.ui64, - rpkts->value.ui64, - ierrs->value.ui32, - oerrs->value.ui32, -#else - py_ifc_info = Py_BuildValue("(kkkkkkii)", - wbytes->value.ui32, - rbytes->value.ui32, - wpkts->value.ui32, - rpkts->value.ui32, - ierrs->value.ui32, - oerrs->value.ui32, -#endif - 0, // dropin not supported - 0 // dropout not supported - ); + if (rbytes->data_type == KSTAT_DATA_UINT64) + { + py_ifc_info = Py_BuildValue("(KKKKIIii)", + wbytes->value.ui64, + rbytes->value.ui64, + wpkts->value.ui64, + rpkts->value.ui64, + ierrs->value.ui32, + oerrs->value.ui32, + 0, // dropin not supported + 0 // dropout not supported + ); + } + else + { + py_ifc_info = Py_BuildValue("(IIIIIIii)", + wbytes->value.ui32, + rbytes->value.ui32, + wpkts->value.ui32, + rpkts->value.ui32, + ierrs->value.ui32, + oerrs->value.ui32, + 0, // dropin not supported + 0 // dropout not supported + ); + } if (!py_ifc_info) goto error; if (PyDict_SetItemString(py_retdict, ksp->ks_name, py_ifc_info)) From c18e61eaef2d66a8e5bcc7e8aec57c2ed4d8d1e1 Mon Sep 17 00:00:00 2001 From: Arnon Yaari Date: Sun, 6 Sep 2015 11:34:11 +0300 Subject: [PATCH 3/4] update history and credits --- CREDITS | 2 +- HISTORY.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CREDITS b/CREDITS index 32977c63b..baff88c45 100644 --- a/CREDITS +++ b/CREDITS @@ -328,4 +328,4 @@ I: 659 N: wiggin15 W: https://github.com/wiggin15 -I: 607, 610 +I: 517, 607, 610 diff --git a/HISTORY.rst b/HISTORY.rst index 051efd3d0..f3766d0b3 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -7,6 +7,7 @@ Bug tracker at https://github.com/giampaolo/psutil/issues - #677: [Linux] can't install psutil due to bug in setup.py. - #610: [SunOS] fix build and tests on Solaris 10 +- #517: [SunOS] fix net_io_counters on Solaris 10 3.2.0 - 2015-09-02 From 5fed050ae9236efa0eaf2f219e44a83d23dddb05 Mon Sep 17 00:00:00 2001 From: Arnon Yaari Date: Sun, 6 Sep 2015 12:22:52 +0300 Subject: [PATCH 4/4] fix review comments --- HISTORY.rst | 3 ++- psutil/_psutil_sunos.c | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index f3766d0b3..d8489e466 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -7,7 +7,8 @@ Bug tracker at https://github.com/giampaolo/psutil/issues - #677: [Linux] can't install psutil due to bug in setup.py. - #610: [SunOS] fix build and tests on Solaris 10 -- #517: [SunOS] fix net_io_counters on Solaris 10 +- #517: [SunOS] net_io_counters failed to detect network interfaces + correctly on Solaris 10 3.2.0 - 2015-09-02 diff --git a/psutil/_psutil_sunos.c b/psutil/_psutil_sunos.c index 9f1f5e59a..5910eb59a 100644 --- a/psutil/_psutil_sunos.c +++ b/psutil/_psutil_sunos.c @@ -689,8 +689,10 @@ psutil_net_io_counters(PyObject *self, PyObject *args) { goto error; sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock == -1) + if (sock == -1) { + PyErr_SetFromErrno(PyExc_OSError); goto error; + } ksp = kc->kc_chain; while (ksp != NULL) { @@ -1170,8 +1172,10 @@ psutil_net_if_stats(PyObject* self, PyObject* args) { if (kc == NULL) goto error; sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock == -1) + if (sock == -1) { + PyErr_SetFromErrno(PyExc_OSError); goto error; + } for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) { if (strcmp(ksp->ks_class, "net") == 0) {