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);