http://git-wip-us.apache.org/repos/asf/ambari/blob/a52f8a55/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_sunos.c
----------------------------------------------------------------------
diff --git 
a/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_sunos.c
 
b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_sunos.c
new file mode 100644
index 0000000..f02415c
--- /dev/null
+++ 
b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_sunos.c
@@ -0,0 +1,1290 @@
+/*
+ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Functions specific to Sun OS Solaris platforms.
+ *
+ * Thanks to Justin Venus who originally wrote a consistent part of
+ * this in Cython which I later on translated in C.
+ */
+
+
+#include <Python.h>
+
+// fix for "Cannot use procfs in the large file compilation environment"
+// error, see:
+// http://sourceware.org/ml/gdb-patches/2010-11/msg00336.html
+#undef _FILE_OFFSET_BITS
+#define _STRUCTURED_PROC 1
+
+// fix compilation issue on SunOS 5.10, see:
+// https://code.google.com/p/psutil/issues/detail?id=421
+#define NEW_MIB_COMPLIANT
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/proc.h>
+#include <sys/swap.h>
+#include <sys/sysinfo.h>
+#include <sys/mntent.h>  // for MNTTAB
+#include <sys/mnttab.h>
+#include <sys/procfs.h>
+#include <fcntl.h>
+#include <utmpx.h>
+#include <kstat.h>
+#include <sys/ioctl.h>
+#include <sys/tihdr.h>
+#include <stropts.h>
+#include <inet/tcp.h>
+#include <arpa/inet.h>
+
+#include "_psutil_sunos.h"
+
+
+#define TV2DOUBLE(t)   (((t).tv_nsec * 0.000000001) + (t).tv_sec)
+
+/*
+ * Read a file content and fills a C structure with it.
+ */
+int
+psutil_file_to_struct(char *path, void *fstruct, size_t size)
+{
+    int fd;
+    size_t nbytes;
+    fd = open(path, O_RDONLY);
+    if (fd == -1) {
+        PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
+        return 0;
+    }
+    nbytes = read(fd, fstruct, size);
+    if (nbytes <= 0) {
+        close(fd);
+        PyErr_SetFromErrno(PyExc_OSError);
+        return 0;
+    }
+    if (nbytes != size) {
+        close(fd);
+        PyErr_SetString(PyExc_RuntimeError, "structure size mismatch");
+        return 0;
+    }
+    close(fd);
+    return nbytes;
+}
+
+
+/*
+ * Return process ppid, rss, vms, ctime, nice, nthreads, status and tty
+ * as a Python tuple.
+ */
+static PyObject *
+psutil_proc_basic_info(PyObject *self, PyObject *args)
+{
+    int pid;
+    char path[100];
+    psinfo_t info;
+
+    if (! PyArg_ParseTuple(args, "i", &pid))
+        return NULL;
+    sprintf(path, "/proc/%i/psinfo", pid);
+    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
+        return NULL;
+    return Py_BuildValue("ikkdiiik",
+                         info.pr_ppid,              // parent pid
+                         info.pr_rssize,            // rss
+                         info.pr_size,              // vms
+                         TV2DOUBLE(info.pr_start),  // create time
+                         info.pr_lwp.pr_nice,       // nice
+                         info.pr_nlwp,              // no. of threads
+                         info.pr_lwp.pr_state,      // status code
+                         info.pr_ttydev             // tty nr
+                        );
+}
+
+
+/*
+ * Return process name and args as a Python tuple.
+ */
+static PyObject *
+psutil_proc_name_and_args(PyObject *self, PyObject *args)
+{
+    int pid;
+    char path[100];
+    psinfo_t info;
+
+    if (! PyArg_ParseTuple(args, "i", &pid))
+        return NULL;
+    sprintf(path, "/proc/%i/psinfo", pid);
+    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
+        return NULL;
+    return Py_BuildValue("ss", info.pr_fname, info.pr_psargs);
+}
+
+
+/*
+ * Return process user and system CPU times as a Python tuple.
+ */
+static PyObject *
+psutil_proc_cpu_times(PyObject *self, PyObject *args)
+{
+    int pid;
+    char path[100];
+    pstatus_t info;
+
+    if (! PyArg_ParseTuple(args, "i", &pid))
+        return NULL;
+    sprintf(path, "/proc/%i/status", pid);
+    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
+        return NULL;
+    // results are more precise than os.times()
+    return Py_BuildValue("dd",
+                         TV2DOUBLE(info.pr_utime),
+                         TV2DOUBLE(info.pr_stime));
+}
+
+
+/*
+ * Return process uids/gids as a Python tuple.
+ */
+static PyObject *
+psutil_proc_cred(PyObject *self, PyObject *args)
+{
+    int pid;
+    char path[100];
+    prcred_t info;
+
+    if (! PyArg_ParseTuple(args, "i", &pid))
+        return NULL;
+    sprintf(path, "/proc/%i/cred", pid);
+    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
+        return NULL;
+    return Py_BuildValue("iiiiii",
+                         info.pr_ruid, info.pr_euid, info.pr_suid,
+                         info.pr_rgid, info.pr_egid, info.pr_sgid);
+}
+
+
+/*
+ * Return process uids/gids as a Python tuple.
+ */
+static PyObject *
+psutil_proc_num_ctx_switches(PyObject *self, PyObject *args)
+{
+    int pid;
+    char path[100];
+    prusage_t info;
+
+    if (! PyArg_ParseTuple(args, "i", &pid))
+        return NULL;
+    sprintf(path, "/proc/%i/usage", pid);
+    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
+        return NULL;
+    return Py_BuildValue("kk", info.pr_vctx, info.pr_ictx);
+}
+
+
+/*
+ * Process IO counters.
+ *
+ * Commented out and left here as a reminder.  Apparently we cannot
+ * retrieve process IO stats because:
+ * - 'pr_ioch' is a sum of chars read and written, with no distinction
+ * - 'pr_inblk' and 'pr_oublk', which should be the number of bytes
+ *    read and written, hardly increase and according to:
+ *    http://www.brendangregg.com/Perf/paper_diskubyp1.pdf
+ *    ...they should be meaningless anyway.
+ *
+static PyObject*
+proc_io_counters(PyObject* self, PyObject* args)
+{
+    int pid;
+    char path[100];
+    prusage_t info;
+
+    if (! PyArg_ParseTuple(args, "i", &pid)) {
+        return NULL;
+    }
+    sprintf(path, "/proc/%i/usage", pid);
+    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info))) {
+        return NULL;
+    }
+
+    // On Solaris we only have 'pr_ioch' which accounts for bytes read
+    // *and* written.
+    // 'pr_inblk' and 'pr_oublk' should be expressed in blocks of
+    // 8KB according to:
+    // http://www.brendangregg.com/Perf/paper_diskubyp1.pdf  (pag. 8)
+    return Py_BuildValue("kkkk",
+                         info.pr_ioch,
+                         info.pr_ioch,
+                         info.pr_inblk,
+                         info.pr_oublk);
+}
+ */
+
+
+/*
+ * Return information about a given process thread.
+ */
+static PyObject *
+psutil_proc_query_thread(PyObject *self, PyObject *args)
+{
+    int pid, tid;
+    char path[100];
+    lwpstatus_t info;
+
+    if (! PyArg_ParseTuple(args, "ii", &pid, &tid))
+        return NULL;
+    sprintf(path, "/proc/%i/lwp/%i/lwpstatus", pid, tid);
+    if (! psutil_file_to_struct(path, (void *)&info, sizeof(info)))
+        return NULL;
+    return Py_BuildValue("dd",
+                         TV2DOUBLE(info.pr_utime),
+                         TV2DOUBLE(info.pr_stime));
+}
+
+
+/*
+ * Return information about system virtual memory.
+ */
+static PyObject *
+psutil_swap_mem(PyObject *self, PyObject *args)
+{
+// XXX (arghhh!)
+// total/free swap mem: commented out as for some reason I can't
+// manage to get the same results shown by "swap -l", despite the
+// code below is exactly the same as:
+// http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/
+//    cmd/swap/swap.c
+// We're going to parse "swap -l" output from Python (sigh!)
+
+/*
+    struct swaptable     *st;
+    struct swapent    *swapent;
+    int    i;
+    struct stat64 statbuf;
+    char *path;
+    char fullpath[MAXPATHLEN+1];
+    int    num;
+
+    if ((num = swapctl(SC_GETNSWP, NULL)) == -1) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return NULL;
+    }
+    if (num == 0) {
+        PyErr_SetString(PyExc_RuntimeError, "no swap devices configured");
+        return NULL;
+    }
+    if ((st = malloc(num * sizeof(swapent_t) + sizeof (int))) == NULL) {
+        PyErr_SetString(PyExc_RuntimeError, "malloc failed");
+        return NULL;
+    }
+    if ((path = malloc(num * MAXPATHLEN)) == NULL) {
+        PyErr_SetString(PyExc_RuntimeError, "malloc failed");
+        return NULL;
+    }
+    swapent = st->swt_ent;
+    for (i = 0; i < num; i++, swapent++) {
+        swapent->ste_path = path;
+        path += MAXPATHLEN;
+    }
+    st->swt_n = num;
+    if ((num = swapctl(SC_LIST, st)) == -1) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return NULL;
+    }
+
+    swapent = st->swt_ent;
+    long t = 0, f = 0;
+    for (i = 0; i < num; i++, swapent++) {
+        int diskblks_per_page =(int)(sysconf(_SC_PAGESIZE) >> DEV_BSHIFT);
+        t += (long)swapent->ste_pages;
+        f += (long)swapent->ste_free;
+    }
+
+    free(st);
+    return Py_BuildValue("(kk)", t, f);
+*/
+
+    kstat_ctl_t *kc;
+    kstat_t     *k;
+    cpu_stat_t  *cpu;
+    int         cpu_count = 0;
+    int         flag = 0;
+    uint_t      sin = 0;
+    uint_t      sout = 0;
+
+    kc = kstat_open();
+    if (kc == NULL) {
+        return PyErr_SetFromErrno(PyExc_OSError);;
+    }
+
+    k = kc->kc_chain;
+    while (k != NULL) {
+        if ((strncmp(k->ks_name, "cpu_stat", 8) == 0) && \
+                (kstat_read(kc, k, NULL) != -1) )
+        {
+            flag = 1;
+            cpu = (cpu_stat_t *) k->ks_data;
+            sin += cpu->cpu_vminfo.pgswapin;    // num pages swapped in
+            sout += cpu->cpu_vminfo.pgswapout;  // num pages swapped out
+        }
+        cpu_count += 1;
+        k = k->ks_next;
+    }
+    kstat_close(kc);
+    if (!flag) {
+        PyErr_SetString(PyExc_RuntimeError, "no swap device was found");
+        return NULL;
+    }
+    return Py_BuildValue("(II)", sin, sout);
+}
+
+
+/*
+ * Return users currently connected on the system.
+ */
+static PyObject *
+psutil_users(PyObject *self, PyObject *args)
+{
+    struct utmpx *ut;
+    PyObject *ret_list = PyList_New(0);
+    PyObject *tuple = NULL;
+    PyObject *user_proc = NULL;
+
+    if (ret_list == NULL)
+        return NULL;
+
+    while (NULL != (ut = getutxent())) {
+        if (ut->ut_type == USER_PROCESS)
+            user_proc = Py_True;
+        else
+            user_proc = Py_False;
+        tuple = Py_BuildValue(
+            "(sssfO)",
+            ut->ut_user,              // username
+            ut->ut_line,              // tty
+            ut->ut_host,              // hostname
+            (float)ut->ut_tv.tv_sec,  // tstamp
+            user_proc);               // (bool) user process
+        if (tuple == NULL)
+            goto error;
+        if (PyList_Append(ret_list, tuple))
+            goto error;
+        Py_DECREF(tuple);
+    }
+    endutent();
+
+    return ret_list;
+
+error:
+    Py_XDECREF(tuple);
+    Py_DECREF(ret_list);
+    if (ut != NULL)
+        endutent();
+    return NULL;
+}
+
+
+/*
+ * Return disk mounted partitions as a list of tuples including device,
+ * mount point and filesystem type.
+ */
+static PyObject *
+psutil_disk_partitions(PyObject *self, PyObject *args)
+{
+    FILE *file;
+    struct mnttab mt;
+    PyObject *py_retlist = PyList_New(0);
+    PyObject *py_tuple = NULL;
+
+    if (py_retlist == NULL)
+        return NULL;
+
+    file = fopen(MNTTAB, "rb");
+    if (file == NULL) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        goto error;
+    }
+
+    while (getmntent(file, &mt) == 0) {
+        py_tuple = Py_BuildValue(
+            "(ssss)",
+            mt.mnt_special,   // device
+            mt.mnt_mountp,    // mount point
+            mt.mnt_fstype,    // fs type
+            mt.mnt_mntopts);  // options
+        if (py_tuple == NULL)
+            goto error;
+        if (PyList_Append(py_retlist, py_tuple))
+            goto error;
+        Py_DECREF(py_tuple);
+
+    }
+    fclose(file);
+    return py_retlist;
+
+error:
+    Py_XDECREF(py_tuple);
+    Py_DECREF(py_retlist);
+    if (file != NULL)
+        fclose(file);
+    return NULL;
+}
+
+
+/*
+ * Return system-wide CPU times.
+ */
+static PyObject *
+psutil_per_cpu_times(PyObject *self, PyObject *args)
+{
+    kstat_ctl_t *kc;
+    kstat_t *ksp;
+    cpu_stat_t cs;
+    int numcpus;
+    int i;
+    PyObject *py_retlist = PyList_New(0);
+    PyObject *py_cputime = NULL;
+
+    if (py_retlist == NULL)
+        return NULL;
+
+    kc = kstat_open();
+    if (kc == NULL) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        goto error;
+    }
+
+    numcpus = sysconf(_SC_NPROCESSORS_ONLN) - 1;
+    for (i = 0; i <= numcpus; i++) {
+        ksp = kstat_lookup(kc, "cpu_stat", i, NULL);
+        if (ksp == NULL) {
+            PyErr_SetFromErrno(PyExc_OSError);
+            goto error;
+        }
+        if (kstat_read(kc, ksp, &cs) == -1) {
+            PyErr_SetFromErrno(PyExc_OSError);
+            goto error;
+        }
+
+        py_cputime = Py_BuildValue("ffff",
+                                   (float)cs.cpu_sysinfo.cpu[CPU_USER],
+                                   (float)cs.cpu_sysinfo.cpu[CPU_KERNEL],
+                                   (float)cs.cpu_sysinfo.cpu[CPU_IDLE],
+                                   (float)cs.cpu_sysinfo.cpu[CPU_WAIT]);
+        if (py_cputime == NULL)
+            goto error;
+        if (PyList_Append(py_retlist, py_cputime))
+            goto error;
+        Py_DECREF(py_cputime);
+
+    }
+
+    kstat_close(kc);
+    return py_retlist;
+
+error:
+    Py_XDECREF(py_cputime);
+    Py_DECREF(py_retlist);
+    if (kc != NULL)
+        kstat_close(kc);
+    return NULL;
+}
+
+
+/*
+ * Return disk IO statistics.
+ */
+static PyObject *
+psutil_disk_io_counters(PyObject *self, PyObject *args)
+{
+    kstat_ctl_t *kc;
+    kstat_t *ksp;
+    kstat_io_t kio;
+    PyObject *py_retdict = PyDict_New();
+    PyObject *py_disk_info = NULL;
+
+    if (py_retdict == NULL)
+        return NULL;
+    kc = kstat_open();
+    if (kc == NULL) {
+        PyErr_SetFromErrno(PyExc_OSError);;
+        goto error;
+    }
+    ksp = kc->kc_chain;
+    while (ksp != NULL) {
+        if (ksp->ks_type == KSTAT_TYPE_IO) {
+            if (strcmp(ksp->ks_class, "disk") == 0) {
+                if (kstat_read(kc, ksp, &kio) == -1) {
+                    kstat_close(kc);
+                    return PyErr_SetFromErrno(PyExc_OSError);;
+                }
+                py_disk_info = Py_BuildValue(
+                    "(IIKKLL)",
+                    kio.reads,
+                    kio.writes,
+                    kio.nread,
+                    kio.nwritten,
+                    kio.rtime / 1000 / 1000,  // from nano to milli secs
+                    kio.wtime / 1000 / 1000   // from nano to milli secs
+                );
+                if (!py_disk_info)
+                    goto error;
+                if (PyDict_SetItemString(py_retdict, ksp->ks_name,
+                                         py_disk_info))
+                    goto error;
+                Py_DECREF(py_disk_info);
+            }
+        }
+        ksp = ksp->ks_next;
+    }
+    kstat_close(kc);
+
+    return py_retdict;
+
+error:
+    Py_XDECREF(py_disk_info);
+    Py_DECREF(py_retdict);
+    if (kc != NULL)
+        kstat_close(kc);
+    return NULL;
+}
+
+
+/*
+ * Return process memory mappings.
+ */
+static PyObject *
+psutil_proc_memory_maps(PyObject *self, PyObject *args)
+{
+    int pid;
+    int fd = -1;
+    char path[100];
+    char perms[10];
+    char *name;
+    struct stat st;
+    pstatus_t status;
+
+    prxmap_t *xmap = NULL, *p;
+    off_t size;
+    size_t nread;
+    int nmap;
+    uintptr_t pr_addr_sz;
+    uintptr_t stk_base_sz, brk_base_sz;
+
+    PyObject *pytuple = NULL;
+    PyObject *py_retlist = PyList_New(0);
+
+    if (py_retlist == NULL) {
+        return NULL;
+    }
+    if (! PyArg_ParseTuple(args, "i", &pid)) {
+        goto error;
+    }
+
+    sprintf(path, "/proc/%i/status", pid);
+    if (! psutil_file_to_struct(path, (void *)&status, sizeof(status))) {
+        goto error;
+    }
+
+    sprintf(path, "/proc/%i/xmap", pid);
+    if (stat(path, &st) == -1) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        goto error;
+    }
+
+    size = st.st_size;
+
+    fd = open(path, O_RDONLY);
+    if (fd == -1) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        goto error;
+    }
+
+    xmap = (prxmap_t *)malloc(size);
+    if (xmap == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
+
+    nread = pread(fd, xmap, size, 0);
+    nmap = nread / sizeof(prxmap_t);
+    p = xmap;
+
+    while (nmap) {
+        nmap -= 1;
+        if (p == NULL) {
+            p += 1;
+            continue;
+        }
+
+        perms[0] = '\0';
+        pr_addr_sz = p->pr_vaddr + p->pr_size;
+
+        // perms
+        sprintf(perms, "%c%c%c%c%c%c", p->pr_mflags & MA_READ ? 'r' : '-',
+                p->pr_mflags & MA_WRITE ? 'w' : '-',
+                p->pr_mflags & MA_EXEC ? 'x' : '-',
+                p->pr_mflags & MA_SHARED ? 's' : '-',
+                p->pr_mflags & MA_NORESERVE ? 'R' : '-',
+                p->pr_mflags & MA_RESERVED1 ? '*' : ' ');
+
+        // name
+        if (strlen(p->pr_mapname) > 0) {
+            name = p->pr_mapname;
+        }
+        else {
+            if ((p->pr_mflags & MA_ISM) || (p->pr_mflags & MA_SHM)) {
+                name = "[shmid]";
+            }
+            else {
+                stk_base_sz = status.pr_stkbase + status.pr_stksize;
+                brk_base_sz = status.pr_brkbase + status.pr_brksize;
+
+                if ((pr_addr_sz > status.pr_stkbase) &&
+                        (p->pr_vaddr < stk_base_sz)) {
+                    name = "[stack]";
+                }
+                else if ((p->pr_mflags & MA_ANON) && \
+                         (pr_addr_sz > status.pr_brkbase) && \
+                         (p->pr_vaddr < brk_base_sz)) {
+                    name = "[heap]";
+                }
+                else {
+                    name = "[anon]";
+                }
+            }
+        }
+
+        pytuple = Py_BuildValue("iisslll",
+                                p->pr_vaddr,
+                                pr_addr_sz,
+                                perms,
+                                name,
+                                (long)p->pr_rss * p->pr_pagesize,
+                                (long)p->pr_anon * p->pr_pagesize,
+                                (long)p->pr_locked * p->pr_pagesize);
+        if (!pytuple)
+            goto error;
+        if (PyList_Append(py_retlist, pytuple))
+            goto error;
+        Py_DECREF(pytuple);
+
+        // increment pointer
+        p += 1;
+    }
+
+    close(fd);
+    free(xmap);
+    return py_retlist;
+
+error:
+    if (fd != -1)
+        close(fd);
+    Py_XDECREF(pytuple);
+    Py_DECREF(py_retlist);
+    if (xmap != NULL)
+        free(xmap);
+    return NULL;
+}
+
+
+/*
+ * Return a list of tuples for network I/O statistics.
+ */
+static PyObject *
+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;
+
+    PyObject *py_retdict = PyDict_New();
+    PyObject *py_ifc_info = NULL;
+
+    if (py_retdict == NULL)
+        return NULL;
+    kc = kstat_open();
+    if (kc == NULL)
+        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)) {
+            goto next;
+        }
+
+        if (kstat_read(kc, ksp, NULL) == -1) {
+            errno = 0;
+            continue;
+        }
+
+        rbytes = (kstat_named_t *)kstat_data_lookup(ksp, "rbytes");
+        wbytes = (kstat_named_t *)kstat_data_lookup(ksp, "obytes");
+        rpkts = (kstat_named_t *)kstat_data_lookup(ksp, "ipackets");
+        wpkts = (kstat_named_t *)kstat_data_lookup(ksp, "opackets");
+        ierrs = (kstat_named_t *)kstat_data_lookup(ksp, "ierrors");
+        oerrs = (kstat_named_t *)kstat_data_lookup(ksp, "oerrors");
+
+        if ((rbytes == NULL) || (wbytes == NULL) || (rpkts == NULL) ||
+                (wpkts == NULL) || (ierrs == NULL) || (oerrs == NULL))
+        {
+            PyErr_SetString(PyExc_RuntimeError, "kstat_data_lookup() failed");
+            goto error;
+        }
+
+#if defined(_INT64_TYPE)
+        py_ifc_info = Py_BuildValue("(KKKKkkii)",
+                                    rbytes->value.ui64,
+                                    wbytes->value.ui64,
+                                    rpkts->value.ui64,
+                                    wpkts->value.ui64,
+                                    ierrs->value.ui32,
+                                    oerrs->value.ui32,
+#else
+        py_ifc_info = Py_BuildValue("(kkkkkkii)",
+                                    rbytes->value.ui32,
+                                    wbytes->value.ui32,
+                                    rpkts->value.ui32,
+                                    wpkts->value.ui32,
+                                    ierrs->value.ui32,
+                                    oerrs->value.ui32,
+#endif
+                                    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))
+            goto error;
+        Py_DECREF(py_ifc_info);
+        goto next;
+
+next:
+        ksp = ksp->ks_next;
+    }
+
+    kstat_close(kc);
+    return py_retdict;
+
+error:
+    Py_XDECREF(py_ifc_info);
+    Py_DECREF(py_retdict);
+    if (kc != NULL)
+        kstat_close(kc);
+    return NULL;
+}
+
+
+#ifndef EXPER_IP_AND_ALL_IRES
+#define EXPER_IP_AND_ALL_IRES   (1024+4)
+#endif
+
+// a signaler for connections without an actual status
+static int PSUTIL_CONN_NONE = 128;
+
+/*
+ * Return TCP and UDP connections opened by process.
+ * UNIX sockets are excluded.
+ *
+ * Thanks to:
+ * https://github.com/DavidGriffith/finx/blob/master/
+ *     nxsensor-3.5.0-1/src/sysdeps/solaris.c
+ * ...and:
+ * https://hg.java.net/hg/solaris~on-src/file/tip/usr/src/cmd/
+ *     cmd-inet/usr.bin/netstat/netstat.c
+ */
+static PyObject *
+psutil_net_connections(PyObject *self, PyObject *args)
+{
+    long pid;
+    int sd = NULL;
+    mib2_tcpConnEntry_t *tp = NULL;
+    mib2_udpEntry_t     *ude;
+#if defined(AF_INET6)
+    mib2_tcp6ConnEntry_t *tp6;
+    mib2_udp6Entry_t     *ude6;
+#endif
+    char buf[512];
+    int i, flags, getcode, num_ent, state;
+    char lip[200], rip[200];
+    int lport, rport;
+    int processed_pid;
+    struct strbuf ctlbuf, databuf;
+    struct T_optmgmt_req *tor = (struct T_optmgmt_req *)buf;
+    struct T_optmgmt_ack *toa = (struct T_optmgmt_ack *)buf;
+    struct T_error_ack   *tea = (struct T_error_ack *)buf;
+    struct opthdr        *mibhdr;
+
+    PyObject *py_retlist = PyList_New(0);
+    PyObject *py_tuple = NULL;
+    PyObject *py_laddr = NULL;
+    PyObject *py_raddr = NULL;
+    PyObject *af_filter = NULL;
+    PyObject *type_filter = NULL;
+
+    if (py_retlist == NULL)
+        return NULL;
+    if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter))
+        goto error;
+    if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
+        PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
+        goto error;
+    }
+
+    sd = open("/dev/arp", O_RDWR);
+    if (sd == -1) {
+        PyErr_SetFromErrnoWithFilename(PyExc_OSError, "/dev/arp");
+        goto error;
+    }
+
+    /*
+    XXX - These 2 are used in ifconfig.c but they seem unnecessary
+    ret = ioctl(sd, I_PUSH, "tcp");
+    if (ret == -1) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        goto error;
+    }
+    ret = ioctl(sd, I_PUSH, "udp");
+    if (ret == -1) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        goto error;
+    }
+    */
+
+    // OK, this mess is basically copied and pasted from nxsensor project
+    // which copied and pasted it from netstat source code, mibget()
+    // function.  Also see:
+    // http://stackoverflow.com/questions/8723598/
+    tor->PRIM_type = T_SVR4_OPTMGMT_REQ;
+    tor->OPT_offset = sizeof (struct T_optmgmt_req);
+    tor->OPT_length = sizeof (struct opthdr);
+    tor->MGMT_flags = T_CURRENT;
+    mibhdr = (struct opthdr *)&tor[1];
+    mibhdr->level = EXPER_IP_AND_ALL_IRES;
+    mibhdr->name  = 0;
+    mibhdr->len   = 0;
+
+    ctlbuf.buf = buf;
+    ctlbuf.len = tor->OPT_offset + tor->OPT_length;
+    flags = 0;  // request to be sent in non-priority
+
+    if (putmsg(sd, &ctlbuf, (struct strbuf *)0, flags) == -1) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        goto error;
+    }
+
+    mibhdr = (struct opthdr *)&toa[1];
+    ctlbuf.maxlen = sizeof (buf);
+
+    for (;;) {
+        flags = 0;
+        getcode = getmsg(sd, &ctlbuf, (struct strbuf *)0, &flags);
+
+        if (getcode != MOREDATA ||
+                ctlbuf.len < sizeof (struct T_optmgmt_ack) ||
+                toa->PRIM_type != T_OPTMGMT_ACK ||
+                toa->MGMT_flags != T_SUCCESS)
+        {
+            break;
+        }
+        if (ctlbuf.len >= sizeof (struct T_error_ack) &&
+                tea->PRIM_type == T_ERROR_ACK)
+        {
+            PyErr_SetString(PyExc_RuntimeError, "ERROR_ACK");
+            goto error;
+        }
+        if (getcode == 0 &&
+                ctlbuf.len >= sizeof (struct T_optmgmt_ack) &&
+                toa->PRIM_type == T_OPTMGMT_ACK &&
+                toa->MGMT_flags == T_SUCCESS)
+        {
+            PyErr_SetString(PyExc_RuntimeError, "ERROR_T_OPTMGMT_ACK");
+            goto error;
+        }
+
+        databuf.maxlen = mibhdr->len;
+        databuf.len = 0;
+        databuf.buf = (char *)malloc((int)mibhdr->len);
+        if (!databuf.buf) {
+            PyErr_NoMemory();
+            goto error;
+        }
+
+        flags = 0;
+        getcode = getmsg(sd, (struct strbuf *)0, &databuf, &flags);
+        if (getcode < 0) {
+            PyErr_SetFromErrno(PyExc_OSError);
+            goto error;
+        }
+
+        // TCPv4
+        if (mibhdr->level == MIB2_TCP && mibhdr->name == MIB2_TCP_13) {
+            tp = (mib2_tcpConnEntry_t *)databuf.buf;
+            num_ent = mibhdr->len / sizeof(mib2_tcpConnEntry_t);
+            for (i = 0; i < num_ent; i++, tp++) {
+                processed_pid = tp->tcpConnCreationProcess;
+                if (pid != -1 && processed_pid != pid)
+                    continue;
+                // construct local/remote addresses
+                inet_ntop(AF_INET, &tp->tcpConnLocalAddress, lip, sizeof(lip));
+                inet_ntop(AF_INET, &tp->tcpConnRemAddress, rip, sizeof(rip));
+                lport = tp->tcpConnLocalPort;
+                rport = tp->tcpConnRemPort;
+
+                // contruct python tuple/list
+                py_laddr = Py_BuildValue("(si)", lip, lport);
+                if (!py_laddr)
+                    goto error;
+                if (rport != 0) {
+                    py_raddr = Py_BuildValue("(si)", rip, rport);
+                }
+                else {
+                    py_raddr = Py_BuildValue("()");
+                }
+                if (!py_raddr)
+                    goto error;
+                state = tp->tcpConnEntryInfo.ce_state;
+
+                // add item
+                py_tuple = Py_BuildValue("(iiiNNiI)", -1, AF_INET, SOCK_STREAM,
+                                         py_laddr, py_raddr, state,
+                                         processed_pid);
+                if (!py_tuple) {
+                    goto error;
+                }
+                if (PyList_Append(py_retlist, py_tuple))
+                    goto error;
+                Py_DECREF(py_tuple);
+            }
+        }
+#if defined(AF_INET6)
+        // TCPv6
+        else if (mibhdr->level == MIB2_TCP6 && mibhdr->name == MIB2_TCP6_CONN)
+        {
+            tp6 = (mib2_tcp6ConnEntry_t *)databuf.buf;
+            num_ent = mibhdr->len / sizeof(mib2_tcp6ConnEntry_t);
+
+            for (i = 0; i < num_ent; i++, tp6++) {
+                processed_pid = tp6->tcp6ConnCreationProcess;
+                if (pid != -1 && processed_pid != pid)
+                    continue;
+                // construct local/remote addresses
+                inet_ntop(AF_INET6, &tp6->tcp6ConnLocalAddress, lip, 
sizeof(lip));
+                inet_ntop(AF_INET6, &tp6->tcp6ConnRemAddress, rip, 
sizeof(rip));
+                lport = tp6->tcp6ConnLocalPort;
+                rport = tp6->tcp6ConnRemPort;
+
+                // contruct python tuple/list
+                py_laddr = Py_BuildValue("(si)", lip, lport);
+                if (!py_laddr)
+                    goto error;
+                if (rport != 0) {
+                    py_raddr = Py_BuildValue("(si)", rip, rport);
+                }
+                else {
+                    py_raddr = Py_BuildValue("()");
+                }
+                if (!py_raddr)
+                    goto error;
+                state = tp6->tcp6ConnEntryInfo.ce_state;
+
+                // add item
+                py_tuple = Py_BuildValue("(iiiNNiI)", -1, AF_INET6, 
SOCK_STREAM,
+                                         py_laddr, py_raddr, state, 
processed_pid);
+                if (!py_tuple) {
+                    goto error;
+                }
+                if (PyList_Append(py_retlist, py_tuple))
+                    goto error;
+                Py_DECREF(py_tuple);
+            }
+        }
+#endif
+        // UDPv4
+        else if (mibhdr->level == MIB2_UDP || mibhdr->level == MIB2_UDP_ENTRY) 
{
+            ude = (mib2_udpEntry_t *)databuf.buf;
+            num_ent = mibhdr->len / sizeof(mib2_udpEntry_t);
+            for (i = 0; i < num_ent; i++, ude++) {
+                processed_pid = ude->udpCreationProcess;
+                if (pid != -1 && processed_pid != pid)
+                    continue;
+                // XXX Very ugly hack! It seems we get here only the first
+                // time we bump into a UDPv4 socket.  PID is a very high
+                // number (clearly impossible) and the address does not
+                // belong to any valid interface.  Not sure what else
+                // to do other than skipping.
+                if (processed_pid > 131072)
+                    continue;
+                inet_ntop(AF_INET, &ude->udpLocalAddress, lip, sizeof(lip));
+                lport = ude->udpLocalPort;
+                py_laddr = Py_BuildValue("(si)", lip, lport);
+                if (!py_laddr)
+                    goto error;
+                py_raddr = Py_BuildValue("()");
+                if (!py_raddr)
+                    goto error;
+                py_tuple = Py_BuildValue("(iiiNNiI)", -1, AF_INET, SOCK_DGRAM,
+                                         py_laddr, py_raddr, PSUTIL_CONN_NONE,
+                                         processed_pid);
+                if (!py_tuple) {
+                    goto error;
+                }
+                if (PyList_Append(py_retlist, py_tuple))
+                    goto error;
+                Py_DECREF(py_tuple);
+            }
+        }
+#if defined(AF_INET6)
+        // UDPv6
+        else if (mibhdr->level == MIB2_UDP6 || mibhdr->level == 
MIB2_UDP6_ENTRY) {
+            ude6 = (mib2_udp6Entry_t *)databuf.buf;
+            num_ent = mibhdr->len / sizeof(mib2_udp6Entry_t);
+            for (i = 0; i < num_ent; i++, ude6++) {
+                processed_pid = ude6->udp6CreationProcess;
+                if (pid != -1 && processed_pid != pid)
+                    continue;
+                inet_ntop(AF_INET6, &ude6->udp6LocalAddress, lip, sizeof(lip));
+                lport = ude6->udp6LocalPort;
+                py_laddr = Py_BuildValue("(si)", lip, lport);
+                if (!py_laddr)
+                    goto error;
+                py_raddr = Py_BuildValue("()");
+                if (!py_raddr)
+                    goto error;
+                py_tuple = Py_BuildValue("(iiiNNiI)", -1, AF_INET6, SOCK_DGRAM,
+                                         py_laddr, py_raddr, PSUTIL_CONN_NONE,
+                                         processed_pid);
+                if (!py_tuple) {
+                    goto error;
+                }
+                if (PyList_Append(py_retlist, py_tuple))
+                    goto error;
+                Py_DECREF(py_tuple);
+            }
+        }
+#endif
+        free(databuf.buf);
+    }
+
+    close(sd);
+    return py_retlist;
+
+error:
+    Py_XDECREF(py_tuple);
+    Py_XDECREF(py_laddr);
+    Py_XDECREF(py_raddr);
+    Py_DECREF(py_retlist);
+    // TODO : free databuf
+    if (sd != NULL)
+        close(sd);
+    return NULL;
+}
+
+
+static PyObject *
+psutil_boot_time(PyObject *self, PyObject *args)
+{
+    float boot_time = 0.0;
+    struct utmpx *ut;
+
+    while (NULL != (ut = getutxent())) {
+        if (ut->ut_type == BOOT_TIME) {
+            boot_time = (float)ut->ut_tv.tv_sec;
+            break;
+        }
+    }
+    endutent();
+    if (boot_time != 0.0) {
+        return Py_BuildValue("f", boot_time);
+    }
+    else {
+        PyErr_SetString(PyExc_RuntimeError, "can't determine boot time");
+        return NULL;
+    }
+}
+
+
+/*
+ * Return the number of physical CPU cores on the system.
+ */
+static PyObject *
+psutil_cpu_count_phys(PyObject *self, PyObject *args)
+{
+    kstat_ctl_t *kc;
+    kstat_t *ksp;
+    int ncpus = 0;
+
+    kc = kstat_open();
+    if (kc == NULL)
+        goto error;
+    ksp = kstat_lookup(kc, "cpu_info", -1, NULL);
+    if (ksp == NULL)
+        goto error;
+
+    for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
+        if (strcmp(ksp->ks_module, "cpu_info") != 0)
+            continue;
+        if (kstat_read(kc, ksp, NULL) == NULL)
+            goto error;
+        ncpus += 1;
+    }
+
+    kstat_close(kc);
+    if (ncpus > 0)
+        return Py_BuildValue("i", ncpus);
+    else
+        goto error;
+
+error:
+    // mimic os.cpu_count()
+    if (kc != NULL)
+        kstat_close(kc);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+
+/*
+ * define the psutil C module methods and initialize the module.
+ */
+static PyMethodDef
+PsutilMethods[] =
+{
+    // --- process-related functions
+    {"proc_basic_info", psutil_proc_basic_info, METH_VARARGS,
+     "Return process ppid, rss, vms, ctime, nice, nthreads, status and tty"},
+    {"proc_name_and_args", psutil_proc_name_and_args, METH_VARARGS,
+     "Return process name and args."},
+    {"proc_cpu_times", psutil_proc_cpu_times, METH_VARARGS,
+     "Return process user and system CPU times."},
+    {"proc_cred", psutil_proc_cred, METH_VARARGS,
+     "Return process uids/gids."},
+    {"query_process_thread", psutil_proc_query_thread, METH_VARARGS,
+     "Return info about a process thread"},
+    {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS,
+     "Return process memory mappings"},
+    {"proc_num_ctx_switches", psutil_proc_num_ctx_switches, METH_VARARGS,
+     "Return the number of context switches performed by process"},
+
+    // --- system-related functions
+    {"swap_mem", psutil_swap_mem, METH_VARARGS,
+     "Return information about system swap memory."},
+    {"users", psutil_users, METH_VARARGS,
+     "Return currently connected users."},
+    {"disk_partitions", psutil_disk_partitions, METH_VARARGS,
+     "Return disk partitions."},
+    {"per_cpu_times", psutil_per_cpu_times, METH_VARARGS,
+     "Return system per-CPU times."},
+    {"disk_io_counters", psutil_disk_io_counters, METH_VARARGS,
+     "Return a Python dict of tuples for disk I/O statistics."},
+    {"net_io_counters", psutil_net_io_counters, METH_VARARGS,
+     "Return a Python dict of tuples for network I/O statistics."},
+    {"boot_time", psutil_boot_time, METH_VARARGS,
+     "Return system boot time in seconds since the EPOCH."},
+    {"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS,
+     "Return the number of physical CPUs on the system."},
+    {"net_connections", psutil_net_connections, METH_VARARGS,
+     "Return TCP and UDP syste-wide open connections."},
+
+{NULL, NULL, 0, NULL}
+};
+
+
+struct module_state {
+    PyObject *error;
+};
+
+#if PY_MAJOR_VERSION >= 3
+#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
+#else
+#define GETSTATE(m) (&_state)
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+
+static int
+psutil_sunos_traverse(PyObject *m, visitproc visit, void *arg) {
+    Py_VISIT(GETSTATE(m)->error);
+    return 0;
+}
+
+static int
+psutil_sunos_clear(PyObject *m) {
+    Py_CLEAR(GETSTATE(m)->error);
+    return 0;
+}
+
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    "psutil_sunos",
+    NULL,
+    sizeof(struct module_state),
+    PsutilMethods,
+    NULL,
+    psutil_sunos_traverse,
+    psutil_sunos_clear,
+    NULL
+};
+
+#define INITERROR return NULL
+
+PyMODINIT_FUNC PyInit__psutil_sunos(void)
+
+#else
+#define INITERROR return
+
+void init_psutil_sunos(void)
+#endif
+{
+#if PY_MAJOR_VERSION >= 3
+    PyObject *module = PyModule_Create(&moduledef);
+#else
+    PyObject *module = Py_InitModule("_psutil_sunos", PsutilMethods);
+#endif
+    PyModule_AddIntConstant(module, "SSLEEP", SSLEEP);
+    PyModule_AddIntConstant(module, "SRUN", SRUN);
+    PyModule_AddIntConstant(module, "SZOMB", SZOMB);
+    PyModule_AddIntConstant(module, "SSTOP", SSTOP);
+    PyModule_AddIntConstant(module, "SIDL", SIDL);
+    PyModule_AddIntConstant(module, "SONPROC", SONPROC);
+    PyModule_AddIntConstant(module, "SWAIT", SWAIT);
+
+    PyModule_AddIntConstant(module, "PRNODEV", PRNODEV);  // for process tty
+
+    PyModule_AddIntConstant(module, "TCPS_CLOSED", TCPS_CLOSED);
+    PyModule_AddIntConstant(module, "TCPS_CLOSING", TCPS_CLOSING);
+    PyModule_AddIntConstant(module, "TCPS_CLOSE_WAIT", TCPS_CLOSE_WAIT);
+    PyModule_AddIntConstant(module, "TCPS_LISTEN", TCPS_LISTEN);
+    PyModule_AddIntConstant(module, "TCPS_ESTABLISHED", TCPS_ESTABLISHED);
+    PyModule_AddIntConstant(module, "TCPS_SYN_SENT", TCPS_SYN_SENT);
+    PyModule_AddIntConstant(module, "TCPS_SYN_RCVD", TCPS_SYN_RCVD);
+    PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_1", TCPS_FIN_WAIT_1);
+    PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_2", TCPS_FIN_WAIT_2);
+    PyModule_AddIntConstant(module, "TCPS_LAST_ACK", TCPS_LAST_ACK);
+    PyModule_AddIntConstant(module, "TCPS_TIME_WAIT", TCPS_TIME_WAIT);
+    // sunos specific
+    PyModule_AddIntConstant(module, "TCPS_IDLE", TCPS_IDLE);
+    // sunos specific
+    PyModule_AddIntConstant(module, "TCPS_BOUND", TCPS_BOUND);
+    PyModule_AddIntConstant(module, "PSUTIL_CONN_NONE", PSUTIL_CONN_NONE);
+
+    if (module == NULL) {
+        INITERROR;
+    }
+#if PY_MAJOR_VERSION >= 3
+    return module;
+#endif
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/a52f8a55/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_sunos.h
----------------------------------------------------------------------
diff --git 
a/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_sunos.h
 
b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_sunos.h
new file mode 100644
index 0000000..414a7d8
--- /dev/null
+++ 
b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_sunos.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <Python.h>
+
+// processes
+static PyObject* psutil_proc_basic_info(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_cpu_times(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_cred(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_memory_maps(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_name_and_args(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_num_ctx_switches(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_query_thread(PyObject* self, PyObject* args);
+
+// system
+static PyObject* psutil_boot_time(PyObject* self, PyObject* args);
+static PyObject* psutil_cpu_count_phys(PyObject* self, PyObject* args);
+static PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args);
+static PyObject* psutil_disk_partitions(PyObject* self, PyObject* args);
+static PyObject* psutil_net_io_counters(PyObject* self, PyObject* args);
+static PyObject* psutil_per_cpu_times(PyObject* self, PyObject* args);
+static PyObject* psutil_swap_mem(PyObject* self, PyObject* args);
+static PyObject* psutil_users(PyObject* self, PyObject* args);
+static PyObject* psutil_net_connections(PyObject* self, PyObject* args);

Reply via email to