hawq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r...@apache.org
Subject [19/28] incubator-hawq git commit: HAWQ-837. Add python modules into HAWQ code
Date Tue, 21 Jun 2016 02:41:35 GMT
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/darwin_processtable.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/darwin_processtable.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/darwin_processtable.c
new file mode 100644
index 0000000..0132381
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/darwin_processtable.c
@@ -0,0 +1,131 @@
+/* The MIT License
+ *
+ * Copyright (C) 2009 Erick Tryzelaar
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* ProcessTable functions for arch: Mac OS X */
+
+#include <Python.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
+
+#include "psi.h"
+#include "process.h"
+
+
+/***** Local declarations *****/
+static int psi_sysctl(int *name, int nlen, void **oldval, size_t *oldlenp);
+
+
+/***** ProcessTable methods *****/
+
+
+struct psi_proclist *
+psi_arch_proclist(void)
+{
+    static const int    name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
+    struct kinfo_proc   *result = NULL;
+    size_t              length;
+    int                 i;
+    struct psi_proclist *prl = NULL;
+
+    if (psi_sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1,
+                   (void**)&result, &length) == -1)
+        return NULL;
+    prl = (struct psi_proclist *) psi_malloc(sizeof(struct psi_proclist));
+    if (prl == NULL) {
+        psi_free(result);
+        return NULL;
+    }
+    prl->count = length / sizeof(struct kinfo_proc);
+    prl->pids = (pid_t *) psi_malloc(prl->count * sizeof(pid_t));
+    if (prl->pids == NULL) {
+        psi_free(prl);
+        psi_free(result);
+        return NULL;
+    }
+    for(i = 0; i < prl->count; i++)
+        prl->pids[i] = result[i].kp_proc.p_pid;
+    psi_free(result);
+    return prl;
+}
+
+
+/***** Local functions *****/
+
+
+static int
+psi_sysctl(int *name, int nlen, void **oldval, size_t *oldlenp)
+{
+    int  err;
+    int  done = 0;
+
+    /* We start by calling sysctl with oldval == NULL and oldlenp == 0.  That
+     * will succeed, and set length to the appropriate length.  We then
+     * allocate a buffer of that size and call sysctl again with that buffer.
+     * If that succeeds, we're done.  If that fails with ENOMEM, we have to
+     * throw away our buffer and loop.  Note that the loop causes us to call
+     * sysctl with NULL again; this is necessary because the ENOMEM failure
+     * case sets length to the amount of data returned, not the amount of data
+     * that could have been returned. */
+    do {
+        /* Call sysctl with a NULL buffer. */
+        *oldlenp = 0;
+        err = sysctl(name, nlen, NULL, oldlenp, NULL, 0);
+        if (err == -1)
+            err = errno;
+
+        /* Allocate an appropriately sized buffer based on the results from the
+         * previous call. */
+        if (err == 0) {
+            *oldval = psi_malloc(*oldlenp);
+            if (*oldval == NULL)
+                err = ENOMEM;
+        }
+
+        /* Call sysctl again with the new buffer.  If we get an ENOMEM error,
+         * toss away our buffer and start again. */
+        if (err == 0) {
+            err = sysctl(name, nlen, *oldval, oldlenp, NULL, 0);
+            if (err == -1)
+                err = errno;
+            if (err == 0)
+                done = 1;
+            else if (err == ENOMEM) {
+                assert(*oldval != NULL);
+                psi_free(*oldval);
+                *oldval = NULL;
+                err = 0;
+            }
+        }
+    } while (err == 0 && !done);
+
+    /* Clean up and establish post conditions. */
+    if (err != 0) {
+        if (*oldval != NULL)
+            psi_free(*oldval);
+        *oldval = NULL;
+        PyErr_SetFromErrnoWithFilename(PyExc_OSError, "sysctl()");
+        return -1;
+    }
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/darwin_psi.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/darwin_psi.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/darwin_psi.c
new file mode 100644
index 0000000..66149f0
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/darwin_psi.c
@@ -0,0 +1,93 @@
+/* The MIT License
+ *
+ * Copyright (C) 2008-2009 Floris Bruynooghe
+ *
+ * Copyright (C) 2008-2009 Erick Tryzelaar
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* Darwin implementations of the _psi non-POSIX functions */
+
+#include <Python.h>
+#include <sys/sysctl.h>
+#include "psi.h"
+#include "posix_utils.h"
+
+
+/***** Public functions *****/
+
+/*
+ * arch_boottime(&boottime)
+ *
+ * Fetch system boot time in seconds from sysctl and save in the provided long
+ * pointer.
+ *
+ * Returns: 0 if successful; -1 for failure (Python Exception raised)
+ */
+int
+arch_boottime(struct timespec *boottime)
+{
+    struct timeval kern_boottime;
+    int error;
+    unsigned long length = sizeof(kern_boottime);
+    error = sysctlbyname("kern.boottime", &kern_boottime, &length, NULL, 0);
+    if (error) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return -1;
+    }
+    else {
+        boottime->tv_sec = kern_boottime.tv_sec;
+        boottime->tv_nsec = kern_boottime.tv_usec * 1000;
+    }
+
+    return 0;
+}
+
+
+/*
+ * arch_uptime(&uptime_secs, &idle_secs)
+ *
+ * Fetch system uptime and idle time, in seconds and save in the double
+ * pointers provided.
+ *
+ * Returns: 0 if successful; -1 for failure (Python Exception raised)
+ */
+int
+arch_uptime(struct timespec *uptime)
+{
+    struct timespec boottime;
+    struct timeval now;
+
+    if (arch_boottime(&boottime) == -1) {
+        /* arch_boottime will raise the exception for us. */
+        return -1;
+    }
+
+    if (gettimeofday(&now, NULL) < 0) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return -1;
+    }
+
+    uptime->tv_sec = now.tv_sec - boottime.tv_sec;
+    uptime->tv_nsec = (now.tv_usec * 1000) - boottime.tv_nsec;
+
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/getloadavg.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/getloadavg.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/getloadavg.c
new file mode 100644
index 0000000..843123b
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/getloadavg.c
@@ -0,0 +1,67 @@
+/* The MIT License
+ *
+ * Copyright (C) 2008-2009 Floris Bruynooghe
+ *
+ * Copyright (C) 2008-2009 Abilisoft Ltd.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* Implementation of arch_loadavginfo using the common but nonstandard
+ * getloadavg. */
+
+
+#include <Python.h>
+
+#ifdef SUNOS
+#include <sys/loadavg.h>
+#else
+#include <stdlib.h>
+#endif
+
+#include "psi.h"
+#include "psifuncs.h"
+
+
+struct loadavginfo *
+arch_loadavginfo(void)
+{
+    struct loadavginfo *loadi;
+    double avg[3];
+    int r;
+
+    r = getloadavg(avg, 3);
+    if (r == -1) {
+        PyErr_SetString(PyExc_OSError, "getloadavg() failed");
+        return NULL;
+    } else if (r < 3) {
+        PyErr_Format(PyExc_OSError,
+                     "getloadavg() only returned %d numbers (expected 3)", r);
+        return NULL;
+    }
+    loadi = psi_calloc(sizeof(struct loadavginfo));
+    if (loadi == NULL)
+        return NULL;
+    loadi->one = avg[0];
+    loadi->five = avg[1];
+    loadi->fifteen = avg[2];
+    loadi->loadavg_status = PSI_STATUS_OK;
+    return loadi;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_mount.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_mount.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_mount.c
new file mode 100644
index 0000000..9024c15
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_mount.c
@@ -0,0 +1,156 @@
+/* The MIT License
+ *
+ * Copyright (C) 2009 Erick Tryzelaar
+ *
+ * Copyright (C) 2009 Floris Bruynooghe
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <Python.h>
+
+#include <mntent.h>
+#include <stdlib.h>
+#include <sys/statvfs.h>
+
+#include "psi.h"
+#include "mount.h"
+#include "posix_mount.h"
+
+
+/***** Local declarations *****/
+
+static int set_mntent(psi_mountinfo_t *mounti, struct mntent *mnt);
+
+
+/***** Public functions *****/
+
+psi_mountlist_t *
+psi_arch_mountlist(const int remote)
+{
+    FILE *mntent;
+    struct mntent mnt;
+    char buf[PATH_MAX * 3];     /* size used in autofs so I hope it's okay */
+    psi_mountlist_t *ml = NULL;
+    psi_mountinfo_t *mounti, **mounts;
+
+    /* Open /etc/mtab */
+    mntent = setmntent(_PATH_MOUNTED, "r");
+    if (mntent == NULL)
+        return (psi_mountlist_t *) PyErr_SetFromErrnoWithFilename(
+            PyExc_OSError, _PATH_MOUNTED);
+
+    /* Create our (empty) mountlist */
+    ml = (psi_mountlist_t *)psi_calloc(sizeof(psi_mountlist_t));
+    if (ml == NULL) {
+        fclose(mntent);
+        return NULL;
+    }
+
+    /* Step through each line in the mount file */
+    while (getmntent_r(mntent, &mnt, buf, sizeof(buf)) != NULL) {
+
+        /* Skip remote filesystems if not asked for them */
+        if (!remote &&
+            (strchr(mnt.mnt_fsname, ':') != NULL ||
+             strncmp(mnt.mnt_fsname, "//", 2) == 0))
+            continue;
+
+        /* Allocate space for the mount information */
+        if ((mounti = psi_calloc(sizeof(psi_mountinfo_t))) == NULL) {
+            fclose(mntent);
+            psi_free_mountlist(ml);
+            return NULL;
+        }
+        
+        /* And then allocate more space for the mount list */
+        mounts = (psi_mountinfo_t **)psi_realloc(
+            ml->mounts,
+            (ml->count + 1) * sizeof(psi_mountinfo_t *));
+        if (mounts == NULL) {
+            fclose(mntent);
+            psi_free_mountinfo(mounti);
+            psi_free_mountlist(ml);
+            return NULL;
+        }
+        ml->mounts = mounts;
+        ml->mounts[ml->count] = mounti;
+        ml->count += 1;
+
+        /* Finally add the information to mounti */
+        if (set_mntent(mounti, &mnt) < 0) {
+            fclose(mntent);
+            psi_free_mountlist(ml);
+            return NULL;
+        }
+        if (posix_set_vfs(mounti) < 0) {
+            fclose(mntent);
+            psi_free_mountlist(ml);
+            return NULL;
+        }
+    }
+    if (!feof(mntent)) {        /* Uh oh, we had a read error */
+        endmntent(mntent);
+        psi_free_mountlist(ml);
+        PyErr_Format(PyExc_OSError, "Read error in %s", _PATH_MOUNTED);
+        return NULL;
+    }
+    endmntent(mntent);
+    return ml;
+}
+
+
+/***** Local Functions *****/
+
+
+#define STRDUP(dst, src)                    \
+    if ((dst = psi_strdup(src)) == NULL)    \
+        return -1;                          \
+    dst ## _status = PSI_STATUS_OK
+
+
+static int
+set_mntent(psi_mountinfo_t *mounti, struct mntent *mnt)
+{
+    char *p;
+    int r;
+
+    p = strchr(mnt->mnt_fsname, ':');
+    r = strncmp(mnt->mnt_fsname, "//", 2);
+    if (p == NULL || r != 0) {  /* Local mount */
+        mounti->filesystem_host_status = PSI_STATUS_OK;
+        STRDUP(mounti->filesystem_path, mnt->mnt_fsname);
+    } else
+        if (p != NULL) {
+            *p = '\0';
+            STRDUP(mounti->filesystem_host, mnt->mnt_fsname);
+            STRDUP(mounti->filesystem_path, p + 1);
+        } else {
+            p = strchr(mnt->mnt_fsname + 2, '/');
+            *p = '\0';
+            STRDUP(mounti->filesystem_host, mnt->mnt_fsname + 2);
+            STRDUP(mounti->filesystem_path, p + 1);
+        }
+    STRDUP(mounti->mount_type, mnt->mnt_type);
+    STRDUP(mounti->mount_path, mnt->mnt_dir);
+    STRDUP(mounti->mount_options, mnt->mnt_opts);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_process.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_process.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_process.c
new file mode 100644
index 0000000..e23c8c0
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_process.c
@@ -0,0 +1,771 @@
+/* The MIT License
+ *
+ * Copyright (C) 2007 Chris Miles
+ *
+ * Copyright (C) 2008-2009 Floris Bruynooghe
+ *
+ * Copyright (C) 2008-2009 Abilisoft Ltd.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* Linux implementation of the Process classes */
+
+
+#include <Python.h>
+
+#include <limits.h>
+#include <locale.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#include <asm/param.h>
+
+#include "psi.h"
+#include "process.h"
+#include "procfs_utils.h"
+#include "posix_utils.h"
+#include "linux_utils.h"
+
+
+/* Constant numbers don't matter, but apparently these are copied form
+ * linux/fs/proc/array.c.  Whatever.  --flub */
+#define PROC_STATUS_RUNNING 0
+#define PROC_STATUS_SLEEPING 1
+#define PROC_STATUS_DISKSLEEP 2
+#define PROC_STATUS_STOPPED 4
+#define PROC_STATUS_TRACINGSTOP 8
+#define PROC_STATUS_ZOMBIE 16
+#define PROC_STATUS_DEAD 32
+#define PROC_STATUS_PAGING 64   /* not from array.c  */
+
+
+/***** Local declarations *****/
+static int parse_uid_from_proc_status(struct psi_process *proci,
+                                      const char *line);
+static int parse_gid_from_proc_status(struct psi_process *proci,
+                                      const char *line);
+static int parse_stat(struct psi_process *proci,
+                      const char *stat_buf,
+                      const pid_t pid);
+static int decode_state(const char state);
+static void ticks2timespec(struct timespec *tspec,
+                           const unsigned long long ticks);
+static struct timespec calc_cputime(const struct timespec utime,
+                                    const struct timespec stime);
+static int calc_start_time(struct timespec *start_time,
+                           const unsigned long long starttime);
+static int find_terminal(char **terminal, pid_t pid, int fd);
+
+static int set_exe(struct psi_process *proci, const pid_t pid);
+static int set_arg(struct psi_process *proci, const pid_t pid);
+static int set_env(struct psi_process *proci, const pid_t pid);
+static int set_cwd(struct psi_process *proci, const pid_t pid);
+static int set_ids(struct psi_process *proci, const pid_t pid);
+static int set_stat(struct psi_process *proci, const pid_t pid);
+static int set_term(struct psi_process *proci, pid_t pid);
+
+
+
+/***** Public interfaces from process.h. *****/
+
+
+
+/* The process status flags. */
+#define addconst(CONST) {#CONST, CONST}
+struct psi_flag psi_arch_proc_status_flags[] = {
+    addconst(PROC_STATUS_RUNNING),
+    addconst(PROC_STATUS_SLEEPING),
+    addconst(PROC_STATUS_DISKSLEEP),
+    addconst(PROC_STATUS_STOPPED),
+    addconst(PROC_STATUS_TRACINGSTOP),
+    addconst(PROC_STATUS_ZOMBIE),
+    addconst(PROC_STATUS_DEAD),
+    addconst(PROC_STATUS_PAGING),
+    {NULL, 0}};             /* sentinel */
+
+
+struct psi_process *
+psi_arch_process(const pid_t pid)
+{
+    struct psi_process *proci;
+
+    if (procfs_check_pid(pid) == -1)
+        return NULL;
+    proci = psi_calloc(sizeof(struct psi_process));
+    if (proci == NULL)
+        return NULL;
+    if (set_exe(proci, pid) == -1)
+        return psi_free_process(proci);
+    if (set_arg(proci, pid) == -1)
+        return psi_free_process(proci);
+    if (set_env(proci, pid) == -1)
+        return psi_free_process(proci);
+    if (set_cwd(proci, pid) == -1)
+        return psi_free_process(proci);
+    if (set_ids(proci, pid) == -1)
+        return psi_free_process(proci);
+    if (set_stat(proci, pid) == -1)
+        return psi_free_process(proci);
+    if (set_term(proci, pid) == -1)
+        return psi_free_process(proci);
+    return proci;
+}
+
+
+/***** Local functions *****/
+
+
+/*
+ * terminal_name()
+ *
+ * Returns:
+ *       0 = success
+ *      -1 = Failure and Exception was raised
+ */
+static int
+set_term(struct psi_process *proci, pid_t pid)
+{
+    char *terminal = NULL;
+    int i;
+    int r;
+    int fds[] = {255, 2, 0, 1};
+
+    for (i=0; i<4; i++) {
+        r = find_terminal(&terminal, pid, fds[i]);
+        if (r == -2) {
+            PyErr_Clear();
+            proci->terminal_status = PSI_STATUS_PRIVS;
+            return 0;
+        } else if (r < 0)
+            PyErr_Clear();
+        else if (r == 1)
+            break;
+    }
+    proci->terminal = terminal;
+    proci->terminal_status = PSI_STATUS_OK;
+    return 0;
+}
+
+
+/** Read /proc/pid/stat
+ *
+ * The psi_process members filled by this are: nthreads, ppid, status,
+ * virtual_size, resident_size, flags, user_time, system_time, cpu_time,
+ * priority, nice, start_time, pcpu.  Their matching *_status slots are filled
+ * in too.
+ *
+ * Returns 0 for success; -1 for failure (Exception raised).
+ */
+static int
+set_stat(struct psi_process *proci, const pid_t pid)
+{
+    char *buf;
+    int bufsize;
+    int r;
+
+    bufsize = procfs_read_procfile(&buf, pid, "stat");
+    if (bufsize == -1)
+        return -1;
+    if (bufsize == -2) {
+        proci->ppid_status = PSI_STATUS_PRIVS;
+        proci->pgrp_status = PSI_STATUS_PRIVS;
+        proci->sid_status = PSI_STATUS_PRIVS;
+        proci->priority_status = PSI_STATUS_PRIVS;
+        proci->nice_status = PSI_STATUS_PRIVS;
+        proci->start_time_status = PSI_STATUS_PRIVS;
+        proci->status_status = PSI_STATUS_PRIVS;
+        proci->nthreads_status = PSI_STATUS_PRIVS;
+        proci->terminal_status = PSI_STATUS_PRIVS;
+        proci->utime_status = PSI_STATUS_PRIVS;
+        proci->stime_status = PSI_STATUS_PRIVS;
+        proci->vsz_status = PSI_STATUS_PRIVS;
+        proci->rss_status = PSI_STATUS_PRIVS;
+        proci->pcpu_status = PSI_STATUS_PRIVS;
+        return 0;
+    }
+    r = parse_stat(proci, buf, pid);
+    psi_free(buf);
+    if (r == -1)
+        return -1;
+    return 0;
+}
+
+
+/** Set euid, egid, ruid and rgid members of a psi_process structure
+ *
+ * The matching *_status members will be set too.
+ *
+ * Note that this will also set the RSS value since we're reading
+ * /proc/<pid>/status here and this is the best value for RSS we can get.
+ * This function should probably be renamed to parse_status() or something
+ * like that.
+ */
+static int
+set_ids(struct psi_process *proci, const pid_t pid)
+{
+    char *buf;
+    char *line_start;
+    char *line_end;
+    char *value;
+    int bufsize;
+    int uid_seen = 0;
+    int gid_seen = 0;
+/*     int rss_seen = 0; */
+
+    bufsize = procfs_read_procfile(&buf, pid, "status");
+    if (bufsize == -1)
+        return -1;
+    if (bufsize == -2) {
+        proci->euid_status = PSI_STATUS_PRIVS;
+        proci->ruid_status = PSI_STATUS_PRIVS;
+        proci->egid_status = PSI_STATUS_PRIVS;
+        proci->rgid_status = PSI_STATUS_PRIVS;
+        proci->euser_status = PSI_STATUS_PRIVS;
+        proci->ruser_status = PSI_STATUS_PRIVS;
+        proci->egroup_status = PSI_STATUS_PRIVS;
+        proci->rgroup_status = PSI_STATUS_PRIVS;
+        proci->rss_status = PSI_STATUS_PRIVS;
+        return 0;
+    }
+    line_start = buf;
+    while (line_start < buf + bufsize) {
+        line_end = line_start;
+        while (*line_end != '\n' && line_end <= buf+bufsize)
+            line_end++;
+        *line_end = '\0';
+        value = strchr(line_start, ':');
+        if (value) {
+            *value++ = '\0';    /* terminate line_start & point to value */
+            if (strcmp("Uid", line_start) == 0) {
+                uid_seen = 1;
+                if (parse_uid_from_proc_status(proci, value) < 0) {
+                    psi_free(buf);
+                    return -1;
+                }
+            } else if (strcmp("Gid", line_start) == 0) {
+                gid_seen = 1;
+                if (parse_gid_from_proc_status(proci, value) < 0) {
+                    psi_free(buf);
+                    return -1;
+                }
+            }
+        } /* if (value) */
+        line_start = line_end + 1;
+    } /* while (line_start < buf + bufsize) */
+    psi_free(buf);
+    if (!uid_seen || !gid_seen) {
+        PyErr_Format(
+            PyExc_RuntimeError,
+            "Failed to parse required information from /proc/%d/status",
+            pid);
+        return -1;
+    }
+    return 0;
+}
+
+
+/* XXX: This is exactly the same as set_arg, only with a different
+ *      filename! */
+static int
+set_env(struct psi_process *proci, const pid_t pid)
+{
+    char *buf;
+    char **envv;
+    int envc;
+    int bufsize;
+
+    bufsize = procfs_read_procfile(&buf, pid, "environ");
+    if (bufsize == -1)
+        return -1;
+    if (bufsize == -2) {
+        proci->envc_status = PSI_STATUS_PRIVS;
+        proci->envv_status = PSI_STATUS_PRIVS;
+        return 0;
+    }
+    envc = psi_strings_count(buf, bufsize);
+    envv = psi_strings_to_array(buf, envc);
+    psi_free(buf);
+    if (envv == NULL)
+        return -1;
+    proci->envc = envc;
+    proci->envc_status = PSI_STATUS_OK;
+    proci->envv = envv;
+    proci->envv_status = PSI_STATUS_OK;
+    return 0;
+}
+
+
+/** Set the argument list
+ *
+ * This sets argc, argv and command in the psi_process structure.
+ *
+ * Returns 0 on success, -1 on failure (Python exception raised).
+ */
+static int
+set_arg(struct psi_process *proci, const pid_t pid)
+{
+    char *ptr;
+    char **argv;
+    int argc;
+    int bufsize;
+
+    bufsize = procfs_read_procfile(&proci->command, pid, "cmdline");
+    if (bufsize == -1)
+        return -1;
+    if (bufsize == -2) {
+        proci->argc_status = PSI_STATUS_PRIVS;
+        proci->argv_status = PSI_STATUS_PRIVS;
+        return 0;
+    }
+    argc = psi_strings_count(proci->command, bufsize);
+    argv = psi_strings_to_array(proci->command, argc);
+    if (argv == NULL)
+        return -1;
+    for (ptr = proci->command; ptr-proci->command < bufsize-1; ptr++)
+        if (*ptr == '\0')
+            *ptr = ' ';
+    proci->argc = argc;
+    proci->argc_status = PSI_STATUS_OK;
+    proci->argv = argv;
+    proci->argv_status = PSI_STATUS_OK;
+    proci->command_status = PSI_STATUS_OK;
+    return 0;
+}
+
+
+/** Set the exe and exe_status fields of the psi_process structure
+ *
+ * Returns -1 on failure, 0 on success.
+ */
+static int
+set_exe(struct psi_process *proci, const pid_t pid)
+{
+    char *fname;
+    char *link;
+    int r;
+
+    r = psi_asprintf(&fname, "/proc/%d/exe", pid);
+    if (r == -1)
+        return -1;
+    r = psi_readlink(&link, fname);
+    psi_free(fname);
+    if (r == -2) {
+        PyErr_Clear();
+        proci->exe_status = PSI_STATUS_PRIVS;
+        return 0;
+    } else if (r < 0) {
+        if (procfs_check_pid(pid) < 0)
+            return -1;          /* NoSuchProcessError now set */
+        else {
+            PyErr_Clear();
+            proci->exe_status = PSI_STATUS_NA;
+            return 0;
+        }
+    } else {
+        proci->exe = link;
+        proci->exe_status = PSI_STATUS_OK;
+        return 0;
+    }
+}
+
+
+/** Set the cwd and cwd_status fields of the psi_process structure
+ *
+ * Returns -1 on failure, 0 on success.
+ */
+static int
+set_cwd(struct psi_process *proci, const pid_t pid)
+{
+    PyObject *exc_type, *exc_val, *exc_tb;
+    PyObject *errno_attr;
+    long errno_long;
+    char *fname;
+    char *link;
+    int r;
+
+    r = psi_asprintf(&fname, "/proc/%d/cwd", pid);
+    if (r == -1)
+        return -1;
+    r = psi_readlink(&link, fname);
+    psi_free(fname);
+    if (r == -2) {
+        PyErr_Clear();
+        proci->cwd_status = PSI_STATUS_PRIVS;
+        return 0;
+    } else if (r < 0) {
+        procfs_check_pid(pid);  /* OSError -> NoSuchProcessError if required */
+        /* If the process is a zombie, readlink sets errno to ENOENT since the
+         * target does no longer exist.  But psi still wants to show the
+         * process and should not error out. */
+        if (PyErr_ExceptionMatches(PyExc_OSError)) {
+            PyErr_Fetch(&exc_type, &exc_val, &exc_tb);
+            PyErr_NormalizeException(&exc_type, &exc_val, &exc_tb);
+            errno_attr = PyObject_GetAttrString(exc_val, "errno");
+            errno_long = PyLong_AsLong(errno_attr);
+            Py_DECREF(errno_attr);
+            if (errno_long == ENOENT) {
+                Py_DECREF(exc_type);
+                Py_DECREF(exc_val);
+                Py_XDECREF(exc_tb);
+                proci->cwd_status = PSI_STATUS_NA;
+                return 0;
+            }
+            PyErr_Restore(exc_type, exc_val, exc_tb);
+        }
+        return -1;
+    } else {
+        proci->cwd = link;
+        proci->cwd_status = PSI_STATUS_OK;
+        return 0;
+    }
+}
+
+
+/** Find which file/device a filedescriptor is symlinked too
+ *
+ * This will read a symlink in /proc/<pid>/fd/<fd> and if it is pointing to a
+ * valid file will return the name of that file.  You need to psi_free()
+ * `terminal' after use, but only if you got `1' as return value, otherwise it
+ * won't be allocated.
+ *
+ * Returns:
+ *      -2 = insufficient privileges, exception raised
+ *      -1 = error, exception raised
+ *      0 = no terminal name found, `terminal' set to NULL.
+ *      1 = terminal name found
+ */
+static int
+find_terminal(char **terminal, pid_t pid, int fd)
+{
+    char *path;
+    char *link;
+    int r;
+
+    r = psi_asprintf(&path, "/proc/%d/fd/%d", pid, fd);
+    if (r == -1)
+        return -1;
+    r = psi_readlink(&link, path);
+    psi_free(path);
+    if (r < 0)
+        return r;
+    if (strncmp(link, "/dev/null", 9) != 0) {
+        *terminal = link;
+        return 1;
+    }
+    psi_free(link);
+    terminal = NULL;
+    return 0;
+}
+
+
+/** Calculate elapsed time from jiffies
+ *
+ * @param tspec: The timespec into which the result is stored.
+ * @param ticks: The number of clock ticks aka jiffies.
+ */
+static void
+ticks2timespec(struct timespec *tspec, const unsigned long long ticks)
+{
+    int hz;
+
+    hz = sysconf(_SC_CLK_TCK);
+    tspec->tv_sec = ticks/hz;
+    tspec->tv_nsec = (((double)ticks/hz) - tspec->tv_sec)*1000000000;
+}
+
+
+/** Calculate the cputime from utime and stime
+ *
+ * This really just adds two struct timespec values together.
+ */
+static struct timespec
+calc_cputime(const struct timespec utime, const struct timespec stime)
+{
+    struct timespec cputime;
+
+    cputime.tv_sec = utime.tv_sec + stime.tv_sec;
+    cputime.tv_nsec = (utime.tv_nsec + stime.tv_nsec) % 1000000000;
+    cputime.tv_sec += (utime.tv_nsec + stime.tv_nsec) / 1000000000;
+    return cputime;
+}
+
+
+
+/** Calculate the start time of a proc in seconds since epoch
+ *
+ * @param starttime: The starttime in jiffies since system start.
+ */
+static int
+calc_start_time(struct timespec *start_time, const unsigned long long starttime)
+{
+    struct timespec uptime;
+    struct timespec idle;
+    struct timespec now;
+    struct timeval tv_now;
+    
+    int hz;
+
+    hz = sysconf(_SC_CLK_TCK);
+    if (psi_linux_uptime(&uptime, &idle) < 0)
+        return -1;
+    gettimeofday(&tv_now, NULL);
+    if (&tv_now == NULL) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return -1;
+    }
+    now.tv_sec = tv_now.tv_sec;
+    now.tv_nsec = tv_now.tv_usec * 1000;
+    *start_time = posix_timespec_subtract(&now, &uptime);
+    start_time->tv_sec += starttime/hz;
+    start_time->tv_nsec += ((starttime % hz) * 1000000000)/hz;
+    return 0;
+}
+
+
+/** Decode the state character from /proc/<pid>/stat or /proc/<pid>/status
+ *
+ * Returns an int with the correct PROC_STATUS_* constant in.
+ */
+static int
+decode_state(const char state)
+{
+    int tmpi;
+
+    switch (state) {
+    case 'R':
+        tmpi = PROC_STATUS_RUNNING;
+        break;
+    case 'S':
+        tmpi = PROC_STATUS_SLEEPING;
+        break;
+    case 'D':
+        tmpi = PROC_STATUS_DISKSLEEP;
+        break;
+    case 'Z':
+        tmpi = PROC_STATUS_ZOMBIE;
+        break;
+    case 'T':
+        tmpi = PROC_STATUS_STOPPED;
+        break;
+    case 'W':
+        tmpi = PROC_STATUS_PAGING;
+        break;
+    case 'X':
+        tmpi = PROC_STATUS_DEAD;
+        break;
+    default:
+        PyErr_Format(PyExc_OSError, "Invalid/unknown state: %s", &state);
+        return -1;
+    }
+    return tmpi;
+}
+
+
+/** Reads /prop/<pid>/stat files and fills relevant proc slots.
+ *
+ * Reads /proc/pid/stat files, being careful not to trip over processes with
+ * names like ":-) 1 2 3 4 5 6".
+ *
+ * Note that the RSS value is not read from here.  For some reason it is not
+ * correct here nor in /proc/<pid>/mstat, but it does seem correct in
+ * /proc/<pid>/status so we get it from there.
+ *
+ * Returns 0 for success; -1 for failure (Exception raised).
+ */
+static int
+parse_stat(struct psi_process *proci, const char *stat_buf, const pid_t pid)
+{
+    char *name_start, *name_end;
+    int r;
+
+    /* variables filled from the stat file by scanf */
+    char state;
+    int ppid;
+    int pgrp;
+    int sid;
+    unsigned long utime;
+    unsigned long stime;
+    long priority;
+    long nice;
+    long num_threads;
+    unsigned long long starttime;
+    unsigned long vsize;
+    long rss;
+
+    /* The accounting name is surrounded by parenthesis. */
+    name_start = strchr(stat_buf, '(');
+    name_end = strrchr(stat_buf, ')');
+
+    /* Copy the name and strip off the parenthesis. */
+    proci->name = psi_strndup(name_start + 1, name_end - name_start - 1);
+    if (proci->name == NULL)
+        return -1;
+    proci->name_status = PSI_STATUS_OK;
+
+    /* Note that disabled specs don't have the proper length modifier since
+     * that is illegal.  Check proc(5) if you want to enable one of them. */
+    r = sscanf(name_end + 1,
+               " %c"            /* state */
+               " %d"            /* ppid */
+               " %d"            /* pgrp */
+               " %d"            /* session */
+               " %*d"           /* tty_nr */
+               " %*d"           /* tpgid */
+               " %*u"           /* flags */
+               " %*u"           /* minflt */
+               " %*u"           /* cminflt */
+               " %*u"           /* majflt */
+               " %*u"           /* cmajflt */
+               " %lu"           /* utime */
+               " %lu"           /* stime */
+               " %*u"           /* cutime */
+               " %*d"           /* cstime */
+               " %ld"           /* priority */
+               " %ld"           /* nice */
+               " %ld"           /* num_threads */
+               " %*d"           /* itrealvalue (not maintained) */
+               " %llu"          /* starttime */
+               " %lu"           /* vsize */
+               " %ld"           /* rss */
+               " %*u"           /* rsslim */
+               " %*u"           /* startcode */
+               " %*u"           /* endcode */
+               " %*u"           /* startstack */
+               " %*u"           /* kstkesp */
+               " %*u"           /* kstkeip */
+               " %*u"           /* signal (obsolete) */
+               " %*u"           /* blocked (obsolete) */
+               " %*u"           /* sigignore (obsolete) */
+               " %*u"           /* sigcatch (obsolete) */
+               " %*u"           /* wchan */
+               " %*u"           /* nswap (not maintained) */
+               " %*u"           /* cnswap (not maintained) */
+               " %*d"           /* exit_signal (since 2.1.22) */
+               " %*d"           /* processor (since 2.2.8) */
+#ifdef LINUX2_6
+               " %*u"           /* rt_priority (since 2.5.19) */
+               " %*u"           /* policy (since 2.5.19) */
+#if LINUX2_6_MINOR >= 18
+               " %*u"           /* delayacct_blkio_ticks (since 2.6.18) */
+#endif
+#if LINUX2_6_MINOR >= 24
+               " %*u"           /* guest_time (since 2.6.24) */
+               " %*d"           /* cguest_time (since 2.6.24) */
+#endif
+#endif /* #ifdef LINUX2_6 */
+               ,
+               &state,
+               &ppid,
+               &pgrp,
+               &sid,
+               &utime,
+               &stime,
+               &priority,
+               &nice,
+               &num_threads,
+               &starttime,
+               &vsize,
+               &rss);
+    if (r != 12) {
+        /* XXX I see this happening sometimes, but hard to reproduce.  Maybe
+         *     this happens if the process disappears while the stat file is
+         *     being read, resulting in incomplete data? */
+        PyErr_Format(PyExc_OSError,
+                     "Failed to parse stat file for pid %d", pid);
+        return -1;
+    }
+    proci->status = decode_state(state);
+    proci->status_status = PSI_STATUS_OK;
+    proci->ppid = (pid_t)ppid;
+    proci->ppid_status = PSI_STATUS_OK;
+    proci->pgrp = (pid_t)pgrp;
+    proci->pgrp_status = PSI_STATUS_OK;
+    proci->sid = (pid_t)sid;
+    proci->sid_status = PSI_STATUS_OK;
+    ticks2timespec(&proci->utime, utime);
+    proci->utime_status = PSI_STATUS_OK;
+    ticks2timespec(&proci->stime, stime);
+    proci->stime_status = PSI_STATUS_OK;
+    proci->cputime = calc_cputime(proci->utime, proci->stime);
+    proci->cputime_status = PSI_STATUS_OK;
+    if (priority < 0)
+        proci->priority = -priority - 1;
+    else
+        proci->priority = 0;
+    proci->priority_status = PSI_STATUS_OK;
+    proci->nice = nice;
+    proci->nice_status = PSI_STATUS_OK;
+    proci->nthreads = num_threads;
+    proci->nthreads_status = PSI_STATUS_OK;
+    if (calc_start_time(&proci->start_time, starttime) < 0)
+        return -1;
+    proci->start_time_status = PSI_STATUS_OK;
+    proci->jiffies = starttime;
+    proci->jiffies_status = PSI_STATUS_OK;
+    proci->vsz = vsize;
+    proci->vsz_status = PSI_STATUS_OK;
+    proci->rss = rss * sysconf(_SC_PAGESIZE);
+    proci->rss_status = PSI_STATUS_OK;
+    return 0;
+}
+
+
+static int
+parse_uid_from_proc_status(struct psi_process *proci, const char *line)
+{
+    int ruid, euid, suid, fsuid;
+    int r;
+
+    r = sscanf(line, "%d%d%d%d", &ruid, &euid, &suid, &fsuid);
+    if (r == 4) {
+        proci->ruid = ruid;
+        proci->ruid_status = PSI_STATUS_OK;
+        proci->euid = euid;
+        proci->euid_status = PSI_STATUS_OK;
+        return 0;
+    }
+    else {
+        PyErr_SetString(PyExc_OSError, "Failed to parse UID");
+        return -1;
+    }
+}
+
+
+static int
+parse_gid_from_proc_status(struct psi_process *proci, const char *line)
+{
+    int rgid, egid, sgid, fsgid;
+    int r;
+
+    r = sscanf(line, "%d%d%d%d", &rgid, &egid, &sgid, &fsgid);
+    if (r == 4) {
+        proci->rgid = rgid;
+        proci->rgid_status = PSI_STATUS_OK;
+        proci->egid = egid;
+        proci->egid_status = PSI_STATUS_OK;
+        return 0;
+    }
+    else {
+        PyErr_SetString(PyExc_OSError, "Failed to parse GID");
+        return -1;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_psi.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_psi.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_psi.c
new file mode 100644
index 0000000..f7eefa2
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_psi.c
@@ -0,0 +1,77 @@
+/* The MIT License
+ *
+ * Copyright (C) 2009 Erick Tryzelaar
+ *
+ * Copyright (C) 2009 Floris Bruynooghe
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* Linux implementations of the _psi non-POSIX functions */
+
+#include <Python.h>
+
+#include <stdlib.h>
+
+#include "psifuncs.h"
+#include "linux_utils.h"
+
+
+int
+arch_boottime(struct timespec *boottime) {
+    FILE* fp;
+    char* line = NULL;
+    size_t len = 0;
+    long btime;
+    int found = 0;
+
+    fp = fopen("/proc/stat", "r");
+    if (fp == NULL) {
+        PyErr_SetFromErrnoWithFilename(PyExc_OSError, "/proc/stat");
+        return -1;
+    }
+    while ((getline(&line, &len, fp)) != -1)
+        if (sscanf(line, "btime %ld", &btime) != 0) {
+            found = 1;
+            break;
+        }
+    if (line)
+        free(line);
+    fclose(fp);
+    if (!found) {
+        PyErr_SetString(PyExc_OSError,
+                        "Failed to find btime in /proc/stat");
+        return -1;
+    }
+    boottime->tv_sec = btime;
+    boottime->tv_nsec = 0;
+    return 0;
+}
+
+
+int
+arch_uptime(struct timespec *uptime)
+{
+    struct timespec it;
+    
+    if (psi_linux_uptime(uptime, &it) < 0)
+        return -1;
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_utils.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_utils.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_utils.c
new file mode 100644
index 0000000..979b5ba
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/linux_utils.c
@@ -0,0 +1,83 @@
+/* The MIT License
+ *
+ * Copyright (C) 2009 Floris Bruynooghe
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+/* Utility functions specific to Linux */
+
+
+#include <Python.h>
+
+#include <time.h>
+
+#include "psi.h"
+#include "linux_utils.h"
+#include "posix_utils.h"
+
+
+/** psi_linux_uptime(&uptime, &idletime
+ *
+ * Retrieve the uptime and idle time from /proc/uptime in seconds and save
+ * them in the double * pointers provided.
+ *
+ * This function needs to avoid setlocale() for thread safety, hence the
+ * jumping though hoops to use PyOS_ascii_atof().
+ *
+ * Returns -1 in case of failure, 0 for success.
+ */
+int
+psi_linux_uptime(struct timespec *uptime, struct timespec *idletime)
+{
+    char *uptime_s; 
+    char *idle_s; 
+    char *buf;
+    double uptime_d;
+    double idletime_d;
+    int bufsize; 
+    int r; 
+
+    bufsize = psi_read_file(&buf, "/proc/uptime");
+    if (bufsize < 0)
+        return -1;
+    uptime_s = psi_malloc(bufsize * sizeof(char)); 
+    idle_s = psi_malloc(bufsize * sizeof(char)); 
+    if (uptime_s == NULL || idle_s == NULL) { 
+        psi_free(buf); 
+        psi_FREE(uptime_s); 
+        psi_FREE(idle_s); 
+        return -1; 
+    } 
+    r = sscanf(buf, "%s %s", uptime_s, idle_s); 
+    psi_free(buf); 
+    if (r != 2) { 
+        PyErr_SetString(PyExc_OSError, "Failed to parse /proc/uptime"); 
+        return -1; 
+    }
+    uptime_d = PyOS_string_to_double(uptime_s, NULL, NULL);
+    idletime_d = PyOS_string_to_double(idle_s, NULL, NULL);
+    psi_free(uptime_s); 
+    psi_free(idle_s);
+    *uptime = posix_double2timespec(uptime_d);
+    *idletime = posix_double2timespec(idletime_d);
+    return 0; 
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/posix_arch.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/posix_arch.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/posix_arch.c
new file mode 100644
index 0000000..923cfa9
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/posix_arch.c
@@ -0,0 +1,75 @@
+/* The MIT License
+ *
+ * Copyright (C) 2008-2009 Floris Bruynooghe
+ *
+ * Copyright (C) 2008-2009 Abilisoft Ltd.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* POSIX implementation of the Arch classes */
+
+
+#include <Python.h>
+
+#include <string.h>
+#include <sys/utsname.h>
+
+#include "psi.h"
+#include "arch.h"
+
+
+struct psi_archinfo *
+psi_arch_archinfo(void)
+{
+    struct psi_archinfo *archi;
+    struct utsname uts;
+    int r;
+
+    r = uname(&uts);
+    if( r == -1 ) {
+        PyErr_Format(PyExc_OSError, "uname() system call failed");
+        return NULL;
+    }
+    archi = psi_calloc(sizeof(struct psi_archinfo));
+    if (archi == NULL)
+        return NULL;
+    archi->sysname_status = PSI_STATUS_OK;
+    archi->sysname = psi_strdup(uts.sysname);
+    if (archi->sysname == NULL)
+        return psi_free_archinfo(archi);
+    archi->release_status = PSI_STATUS_OK;
+    archi->release = psi_strdup(uts.release);
+    if (archi->release == NULL)
+        return psi_free_archinfo(archi);
+    archi->version_status = PSI_STATUS_OK;
+    archi->version = psi_strdup(uts.version);
+    if (archi->version == NULL)
+        return psi_free_archinfo(archi);
+    archi->machine_status = PSI_STATUS_OK;
+    archi->machine = psi_strdup(uts.machine);
+    if (archi->machine == NULL)
+        return psi_free_archinfo(archi);
+    archi->nodename_status = PSI_STATUS_OK;
+    archi->nodename = psi_strdup(uts.nodename);
+    if (archi->nodename == NULL)
+        return psi_free_archinfo(archi);
+    return archi;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/posix_mount.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/posix_mount.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/posix_mount.c
new file mode 100644
index 0000000..42a704f
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/posix_mount.c
@@ -0,0 +1,67 @@
+/* The MIT License
+ *
+ * Copyright (C) 2008-2009 Floris Bruynooghe
+ *
+ * Copyright (C) 2008-2009 Abilisoft Ltd.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* Common functions for POSIX process implementations. */
+
+#include <Python.h>
+
+#include <errno.h>
+#include <sys/statvfs.h>
+
+#include "psi.h"
+#include "mount.h"
+#include "posix_mount.h"
+
+
+int
+posix_set_vfs(psi_mountinfo_t *mounti)
+{
+    struct statvfs stat;
+    int r;
+
+    Py_BEGIN_ALLOW_THREADS;
+    r = statvfs(mounti->mount_path, &stat);
+    Py_END_ALLOW_THREADS;
+    if (r < 0) {
+        PyErr_SetFromErrnoWithFilename(PyExc_OSError, mounti->mount_path);
+        return -1;
+    }
+    mounti->frsize = stat.f_frsize;
+    mounti->total = stat.f_blocks;
+    mounti->bfree = stat.f_bfree;
+    mounti->bavail = stat.f_bavail;
+    mounti->files = stat.f_files;
+    mounti->ffree = stat.f_ffree;
+    mounti->favail = stat.f_favail;
+    mounti->frsize_status = PSI_STATUS_OK;
+    mounti->total_status = PSI_STATUS_OK;
+    mounti->bfree_status = PSI_STATUS_OK;
+    mounti->bavail_status = PSI_STATUS_OK;
+    mounti->files_status = PSI_STATUS_OK;
+    mounti->ffree_status = PSI_STATUS_OK;
+    mounti->favail_status = PSI_STATUS_OK;
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/posix_utils.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/posix_utils.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/posix_utils.c
new file mode 100644
index 0000000..4caf79a
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/posix_utils.c
@@ -0,0 +1,167 @@
+/* The MIT License
+ *
+ * Copyright (C) 2008-2009 Floris Bruynooghe
+ *
+ * Copyright (C) 2008-2009 Abilisoft Ltd.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* Common functions for POSIX process implementations. */
+
+#include <Python.h>
+
+#include <errno.h>
+#include <grp.h>
+#include <pwd.h>
+#include <time.h>
+#include <utmpx.h>
+
+#include "psi.h"
+#include "posix_utils.h"
+
+
+/* Global variable for caching, need to read utmp only once. */
+static struct timespec utmpx_boottime = {0, 0};
+
+
+/***** Functions *****/
+
+
+struct timeval
+posix_timeval_subtract(struct timeval *x, struct timeval *y)
+{
+    struct timeval result;
+    long nsec;
+    
+    if (x->tv_usec < y->tv_usec) {
+        nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
+        y->tv_usec -= 1000000 * nsec;
+        y->tv_sec += nsec;
+    }
+    if (x->tv_usec - y->tv_usec > 1000000) {
+        nsec = (x->tv_usec - y->tv_usec) / 1000000;
+        y->tv_usec += 1000000 * nsec;
+        y->tv_sec -= nsec;
+    }
+    result.tv_sec = x->tv_sec - y->tv_sec;
+    result.tv_usec = x->tv_usec - y->tv_usec;
+    return result;
+}
+
+
+struct timespec
+posix_timespec_subtract(struct timespec *x, struct timespec *y)
+{
+    struct timespec result;
+    long nsec;
+    
+    if (x->tv_nsec < y->tv_nsec) {
+        nsec = (y->tv_nsec - x->tv_nsec) / 1000000000 + 1;
+        y->tv_nsec -= 1000000000 * nsec;
+        y->tv_sec += nsec;
+    }
+    if (x->tv_nsec - y->tv_nsec > 1000000000) {
+        nsec = (x->tv_nsec - y->tv_nsec) / 1000000000;
+        y->tv_nsec += 1000000000 * nsec;
+        y->tv_sec -= nsec;
+    }
+    result.tv_sec = x->tv_sec - y->tv_sec;
+    result.tv_nsec = x->tv_nsec - y->tv_nsec;
+    return result;
+}
+
+
+struct timespec
+posix_double2timespec(const double dbl)
+{
+    struct timespec tspec;
+    
+    tspec.tv_sec = (long)dbl;
+    tspec.tv_nsec = (long)((dbl-tspec.tv_sec)*1000000000);
+    return tspec;
+}
+
+
+/** Read boottime from utmpx
+ *
+ * Note that the assignment of uti->ut_tv needs to be done in parts since
+ * Linux does specify it weirdly to keep the same size in 32 and 64-bit.
+ */
+int
+posix_utmpx_boottime(struct timespec *boottime)
+{
+    struct timeval new_time;
+    struct utmpx *uti;
+    struct utmpx id;
+
+    if (utmpx_boottime.tv_sec != 0) {
+        *boottime = utmpx_boottime;
+        return 0;
+    }
+    uti = getutxent();
+    if (uti == NULL) {
+        PyErr_SetString(PyExc_OSError, "Failed to open utmpx database");
+        return -1;
+    }
+    setutxent();
+    id.ut_type = BOOT_TIME;
+    uti = getutxid(&id);
+    if (uti == NULL) {
+        endutxent();
+        PyErr_SetString(PyExc_OSError,
+                        "Failed to find BOOT_TIME in utmpx database");
+        return -1;
+    }
+    utmpx_boottime.tv_sec = uti->ut_tv.tv_sec;
+    utmpx_boottime.tv_nsec = uti->ut_tv.tv_usec * 1000;
+
+    /* Now possibly adjust for clock changes since boot */
+    setutxent();
+    id.ut_type = NEW_TIME;
+    uti = getutxid(&id);
+    while (uti != NULL) {
+        new_time.tv_sec = uti->ut_tv.tv_sec;
+        new_time.tv_usec = uti->ut_tv.tv_usec;
+        id.ut_type = OLD_TIME;
+        uti = getutxid(&id);
+        if (uti == NULL) {
+            PyErr_SetString(PyExc_OSError,
+                            "No matching OLD_TIME record "
+                            "for a NEW_TIME record in utmpx");
+            utmpx_boottime.tv_sec = 0;
+            utmpx_boottime.tv_nsec = 0;
+            return -1;
+        }
+        if (uti->ut_tv.tv_sec > utmpx_boottime.tv_sec ||
+            (uti->ut_tv.tv_sec == utmpx_boottime.tv_sec &&
+             uti->ut_tv.tv_usec * 1000 > utmpx_boottime.tv_nsec)) {
+            utmpx_boottime.tv_sec += new_time.tv_sec - uti->ut_tv.tv_sec;
+            utmpx_boottime.tv_nsec += (new_time.tv_usec -
+                                       uti->ut_tv.tv_usec) * 1000;
+        } else
+            break;
+        id.ut_type = NEW_TIME;
+        uti = getutxid(&id);
+    }
+    endutxent();
+    *boottime = utmpx_boottime;
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/procfs_processtable.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/procfs_processtable.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/procfs_processtable.c
new file mode 100644
index 0000000..b7a562f
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/procfs_processtable.c
@@ -0,0 +1,158 @@
+/* The MIT License
+ *
+ * Copyright (C) 2008-2009 Floris Bruynooghe
+ *
+ * Copyright (C) 2008-2009 Abilisoft Ltd.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* POSIX implementation of the ProcessTable class */
+
+
+#include <Python.h>
+
+#include <dirent.h>
+
+#include "psi.h"
+#include "process.h"
+
+
+#if (defined(SUNOS5) && SUNOS5_MINOR < 10) || defined(AIX)
+#define SCANDIR myscandir
+#else
+#define SCANDIR scandir
+#endif
+
+
+static void
+free_dentlist(struct dirent **dentlist, const int ndirs)
+{
+    int i;
+
+    for (i = 0; i < ndirs; i++)
+        free(dentlist[i]);
+    free(dentlist);
+}
+
+
+#if (defined(SUNOS5) && SUNOS5_MINOR < 10) || defined(AIX)
+
+/** Simplified scandir() implementation
+ *
+ * The scandir() function is hidden somewhere in /usr/ucb/cc on Solaris 8 & 9
+ * and not available by default.  On AIX scandir() does not return any entries
+ * in /proc for some unknown reason, this version does.
+ *
+ * In this version the `select' and `cmp' arguments are ignored.
+ */
+static int
+myscandir(const char *dir,
+          struct dirent ***namelist,
+          int (*select) (const struct dirent *),
+          int (*cmp) (const void *, const void *))
+{
+    DIR *dirp;
+    struct dirent **dentlist;
+    struct dirent **dlp;
+    struct dirent *dentp;
+    struct dirent *dcpy;
+    int dentlist_size = 100;
+    int ndirs = 0;
+
+    dentlist = (struct dirent **)malloc(dentlist_size*sizeof(struct dirent *));
+    if (dentlist == NULL)
+        return -1;
+    dirp = opendir(dir);
+    if (dirp == NULL) {
+        free(dentlist);
+        return -1;
+    }
+    while ((dentp = readdir(dirp)) != NULL) {
+        dcpy = (struct dirent *)malloc(sizeof(struct dirent));
+        if (dcpy == NULL) {
+            free_dentlist(dentlist, ndirs);
+            closedir(dirp);
+            return -1;
+        }
+        memcpy(dcpy, dentp, sizeof(struct dirent));
+        dentlist[ndirs] = dcpy;
+        ndirs++;
+        if (ndirs >= dentlist_size) {
+            dentlist_size += 100;
+            dlp = (struct dirent **)realloc(
+                dentlist, dentlist_size*sizeof(struct dirent *));
+            if (dlp == NULL) {
+                free_dentlist(dentlist, ndirs);
+                closedir(dirp);
+                return -1;
+            }
+            dentlist = dlp;
+        }
+    }
+    closedir(dirp);
+    *namelist = dentlist;
+    return ndirs;
+}
+
+#endif  /* (defined(SUNOS5) && SUNOS5_MINOR < 10) || defined(AIX) */
+
+
+struct psi_proclist *
+psi_arch_proclist(void)
+{
+    struct psi_proclist *prl;
+    struct dirent **dentlist;
+    struct dirent *dentp;
+    pid_t pid;
+    int ndirs;
+    int i;
+
+    errno = 0;
+    ndirs = SCANDIR("/proc", &dentlist, NULL, NULL);
+    if (ndirs == -1)
+        return (struct psi_proclist *) PyErr_SetFromErrnoWithFilename(
+            PyExc_OSError, "/proc");
+    prl = (struct psi_proclist *) psi_malloc(sizeof(struct psi_proclist));
+    if (prl == NULL) {
+        free_dentlist(dentlist, ndirs);
+        return NULL;
+    }
+    prl->pids = (pid_t *) psi_malloc(ndirs * sizeof(pid_t));
+    if (prl->pids == NULL) {
+        psi_free(prl);
+        free_dentlist(dentlist, ndirs);
+        return NULL;
+    }
+    prl->count = 0;
+    for (i = 0; i < ndirs; i++) {
+        dentp = dentlist[i];
+        if (dentp->d_name[0] == '.')
+            continue;           /* skip `.' and `..' */
+        errno = 0;
+        pid = (pid_t)strtol(dentp->d_name, (char**)NULL, 10);
+        if (pid <= 0 || errno)
+            continue;           /* not a /proc/<pid> */
+        prl->pids[prl->count] = pid;
+        prl->count++;
+    }
+    free_dentlist(dentlist, ndirs);
+    return prl;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/procfs_utils.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/procfs_utils.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/procfs_utils.c
new file mode 100644
index 0000000..353edcf
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/procfs_utils.c
@@ -0,0 +1,131 @@
+/* The MIT License
+ *
+ * Copyright (C) 2008-2009 Floris Bruynooghe
+ *
+ * Copyright (C) 2008-2009 Abilisoft Ltd.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* Common functions for POSIX process implementations. */
+
+
+#include <Python.h>
+
+#include <limits.h>
+#include <sys/stat.h>
+
+#include "psi.h"
+#include "process.h"
+#include "procfs_utils.h"
+
+
+int
+procfs_check_pid(pid_t pid)
+{
+    struct stat stati;
+    char *fname;
+    int r;
+
+    r = psi_asprintf(&fname, "/proc/%d", pid);
+    errno = 0;
+    r = stat(fname, &stati);
+    if (r == -1) {
+        if (errno == EACCES)
+            PyErr_SetString(PyExc_OSError, "No read access for /proc");
+        else if (errno == ENOENT)
+            PyErr_Format(PsiExc_NoSuchProcessError,
+                         "No such PID: %ld", (long)pid);
+        else
+            PyErr_SetFromErrnoWithFilename(PyExc_OSError, fname);
+    }
+    psi_free(fname);
+    return r;
+}
+
+
+int
+procfs_read_procfile(char **buf, const pid_t pid, char *fname)
+{
+    char *path;
+    int r;
+
+    *buf = NULL;
+    r = psi_asprintf(&path, "/proc/%d/%s", pid, fname);
+    if (r == -1)
+        return -1;
+    r = psi_read_file(buf, path);
+    psi_free(path);
+    if (r == -1)
+        procfs_check_pid(pid);  /* OSError -> NoSuchProcessError if required */
+    return r;
+}
+
+
+int
+procfs_argv_from_string(char ***argv,
+                        char *argstr,
+                        const unsigned int argc)
+{
+    char *ptr;
+    char *arg;
+    char quote;
+    unsigned int i;
+
+    *argv = (char**)psi_calloc(argc*sizeof(char*));
+    if (*argv == NULL)
+        return -1;
+    ptr = argstr;
+    for (i=0; i < argc; i++) {
+        while (isspace((int)*ptr) && *ptr != '\0')
+            ptr++;
+        if (*ptr == '\0')
+            break;
+        arg = ptr;
+        if (*ptr == '\'' || *ptr == '"') {
+            quote = *ptr;
+            arg++;              /* don't include the quote in the arg */
+            do {
+                ptr++;
+                while (*ptr == '\\') /* skip to next unescaped char */
+                    ptr += 2;
+            } while (*ptr != quote);
+            (*argv)[i] = (char*)psi_malloc(ptr - arg + 1);
+            if ((*argv)[i] == NULL)
+                return -1;
+            strncpy((*argv)[i], arg, ptr-arg);
+            *((*argv)[i] + (ptr-arg)) = '\0';
+        } else {
+            do
+                ptr++;
+            while (!isspace((int)*ptr) && *ptr != '\0');
+            (*argv)[i] = (char*)psi_malloc(ptr - arg + 1);
+            if ((*argv)[i] == NULL)
+
+                return -1;
+            strncpy((*argv)[i], arg, ptr-arg);
+            *((*argv)[i] + (ptr-arg)) = '\0';
+        }
+    }
+    if (i > INT_MAX)
+        return INT_MAX;
+    else
+        return (int)i;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sargs64.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sargs64.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sargs64.c
new file mode 100644
index 0000000..55735c2
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sargs64.c
@@ -0,0 +1,202 @@
+/* The MIT License
+ *
+ * Copyright (C) 2009 Floris Bruynooghe
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* SunOS helper to retrieve arguments and environment variables from a 64-bit
+ * process when Python is compiled as 32-bit. */
+
+/* Note that we avoid reporting errors to stderr since we're not sure where
+ * they would appear.  Stdout gets ignored when we return non-zero so that is
+ * a good place to report errors to. */
+
+/* For now there is no dynamic allocation and if there was this program is
+ * very-short lived anyway.  So any function with an error should just print
+ * the error (for debugging purposes) and call `exit(1)'.  `exit(2)' is
+ * reserved for when there is a permissions problem. */
+
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <procfs.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+#ifdef _ILP32
+#error This helper app should be compiled in 64-bit mode
+#endif 
+
+
+/* Read psinfo into a buffer and return it
+ *
+ * The psinfo variable will be filled in on success.
+ */
+static void
+read_psinfo(psinfo_t *psinfo, const char *pidstr)
+{
+    char path[PATH_MAX];
+    ssize_t r;
+    int fd;
+
+    sprintf(path, "/proc/%s/psinfo", pidstr);
+    fd = open(path, O_RDONLY);
+    if (fd == -1) {
+        printf("Failed to open %s\n", path);
+        exit(1);
+    }
+    r = read(fd, psinfo, sizeof(psinfo_t));
+    if (r == -1) {              /* XXX */
+        printf("errno %d: %s\n", errno, strerror(errno));
+        exit(1);
+    }
+    if (r != sizeof(psinfo_t)) {
+        printf("Read wrong number of bytes from psinfo (%d != %d)\n",
+               (int)r, (int)sizeof(psinfo_t));
+        exit(1);
+    }
+}
+
+
+/* Open the address space (core) of the process
+ *
+ * The fd parameter will contain the open file descriptor of the core on
+ * success.
+ */
+static void
+open_as(int *fd, const char *pidstr)
+{
+    char path[PATH_MAX];
+
+    sprintf(path, "/proc/%s/as", pidstr);
+    *fd = open(path, O_RDONLY);
+    if (*fd == -1) {
+        if (errno == EACCES || errno == EPERM)
+            exit(2);
+        else {
+            printf("Failed to open core: %d, %s", errno, strerror(errno));
+            exit(1);
+        }
+    }
+}
+
+
+/** Read a string from a process core
+ *
+ * This keeps reading characters from the core image, open as file descriptor
+ * `asfd', starting from `offset' until '\0' is read.  Each character,
+ * including the trailing NULL character is written to stdout.
+ */
+static void
+read_str_from_core(const off_t offset, const int asfd)
+{
+    off_t charptr;
+    ssize_t r;
+    char c;
+
+    charptr = offset;
+    do {
+        r = pread(asfd, &c, sizeof(char), charptr++);
+        if (r < 0) {
+            puts("Failed reading char from core\n");
+            exit(1);
+        }
+        putchar(c);
+    } while (c != '\0');
+}
+
+
+/** Retrieve the argument list from process core
+ *
+ * This prints the argv vector on stdout and will terminate with an extra
+ * '\0'.
+ */
+static void
+get_args(const psinfo_t *psinfo, const int asfd)
+{
+    off_t argvoff = (off_t)psinfo->pr_argv;
+    off_t argaddr;              /* not caddr_t because of casting issues */
+    ssize_t r;
+    int i;
+
+    for (i = 0; i < psinfo->pr_argc; i++) {
+        r = pread(asfd, &argaddr, sizeof(off_t), argvoff + i*sizeof(off_t));
+        if (r < 0) {
+            puts("Failed reading argaddr from core\n");
+            exit(1);
+        }
+        read_str_from_core(argaddr, asfd);
+    }
+    putchar('\0');
+}
+
+
+static void
+get_envp(const psinfo_t *psinfo, const int asfd) {
+    off_t envpoff = (off_t)psinfo->pr_envp;
+    off_t envaddr;              /* not caddr_t because of casting issues */
+    ssize_t r;
+    int i = 0;
+
+    r = pread(asfd, &envaddr, sizeof(off_t), envpoff);
+    if (r < 0) {
+        puts("Failed to read envaddr from core\n");
+        exit(1);
+    }
+    while (envaddr != NULL) {
+        read_str_from_core(envaddr, asfd);
+        i++;
+        r = pread(asfd, &envaddr, sizeof(off_t), envpoff + i*sizeof(off_t));
+        if (r < 0) {
+            puts("Failed to read envaddr from core (bis)\n");
+            exit(1);
+        }
+    }
+    putchar('\0');
+}
+
+
+int
+main(int argc, char **argv)
+{
+    psinfo_t psinfo;
+    int fd;
+
+    if (argc != 2) {
+        printf("Wrong argument count: %d\n", argc);
+        exit(1);
+    }
+    read_psinfo(&psinfo, argv[1]);
+    if (psinfo.pr_dmodel != PR_MODEL_LP64) {
+        puts("psinfo.pr_dmodel != PR_MODEL_LP64\n");
+        exit(1);
+    }
+    open_as(&fd, argv[1]);
+    get_args(&psinfo, fd);
+    get_envp(&psinfo, fd);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/80e25b46/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sunos_mount.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sunos_mount.c b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sunos_mount.c
new file mode 100644
index 0000000..e0c1557
--- /dev/null
+++ b/tools/bin/pythonSrc/PSI-0.3b2_gp/src/arch/sunos_mount.c
@@ -0,0 +1,171 @@
+/* The MIT License
+ *
+ * Copyright (C) 2009 Erick Tryzelaar
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <Python.h>
+
+#include <stdio.h>
+#include <sys/mnttab.h>
+#include <sys/statvfs.h>
+#include <sys/types.h>
+
+#include "psi.h"
+#include "mount.h"
+
+
+/***** Local declarations *****/
+
+static int set_mntent(psi_mountinfo_t *mounti, struct mnttab *mntent);
+static int set_vfs(psi_mountinfo_t *mounti);
+
+
+/***** Public functions *****/
+
+psi_mountlist_t *
+psi_arch_mountlist(const int remote)
+{
+    FILE *mnttab;
+    struct mnttab mntent;
+    psi_mountlist_t *ml = NULL;
+    psi_mountinfo_t *mounti, **mounts;
+    int rc;
+
+    /* Open up the system's mount information file */
+    if ((mnttab = fopen(MNTTAB, "r")) == NULL) {
+        PyErr_SetFromErrnoWithFilename(PyExc_OSError, MNTTAB);
+        return NULL;
+    }
+
+    /* Create our (empty) mountlist */
+    ml = (psi_mountlist_t *)psi_calloc(sizeof(psi_mountlist_t));
+    if (ml == NULL) {
+        fclose(mnttab);
+        return NULL;
+    }
+
+    /* Step through each line in the mount file */
+    while ((rc = getmntent(mnttab, &mntent)) == 0) {
+        if (!remote && strchr(mntent.mnt_special, ':') != NULL)
+            continue;           /* Skip remote filesystems */
+        if ((mounti = psi_calloc(sizeof(psi_mountinfo_t))) == NULL) {
+            fclose(mnttab);
+            psi_free_mountlist(ml);
+            return NULL;
+        }
+        mounts = (psi_mountinfo_t **)psi_realloc(
+            ml->mounts,
+            (ml->count + 1) * sizeof(psi_mountinfo_t *));
+        if (mounts == NULL) {
+            fclose(mnttab);
+            psi_free_mountinfo(mounti);
+            psi_free_mountlist(ml);
+            return NULL;
+        }
+        ml->mounts = mounts;
+        ml->mounts[ml->count] = mounti;
+        ml->count += 1;
+
+        /* Finally add the information to mounti */
+        if (set_mntent(mounti, &mntent) < 0) {
+            fclose(mnttab);
+            psi_free_mountlist(ml);
+            return NULL;
+        }
+        if (set_vfs(mounti) < 0) {
+            fclose(mnttab);
+            psi_free_mountlist(ml);
+            return NULL;
+        }
+    }
+    fclose(mnttab);
+    if (rc != -1) {             /* Uh oh, we had a read error */
+        psi_free_mountlist(ml);
+        PyErr_Format(PyExc_OSError, "Read error in %s", MNTTAB);
+        return NULL;
+    }
+    return ml;
+}
+
+
+/***** Local Functions *****/
+
+
+#define STRDUP(dst, src)                    \
+    if ((dst = psi_strdup(src)) == NULL)    \
+        return -1;                          \
+    dst ## _status = PSI_STATUS_OK
+
+
+static int
+set_mntent(psi_mountinfo_t *mounti, struct mnttab *mntent)
+{
+    char *p;
+
+    p = strchr(mntent->mnt_special, ':');
+    if (p == NULL) {            /* Local mount */
+        mounti->filesystem_host_status = PSI_STATUS_OK;
+        STRDUP(mounti->filesystem_path, mntent->mnt_special);
+    } else {
+        *p = '\0';
+        STRDUP(mounti->filesystem_host, mntent->mnt_special);
+        STRDUP(mounti->filesystem_path, p + 1);
+    }
+    STRDUP(mounti->mount_type, mntent->mnt_fstype);
+    STRDUP(mounti->mount_path, mntent->mnt_mountp);
+    STRDUP(mounti->mount_options, mntent->mnt_mntopts);
+    return 0;
+}
+
+
+/** Set the filesystem size information
+ *
+ * This information comes from the POSIX statvfs() call.
+ */
+static int set_vfs(psi_mountinfo_t *mounti)
+{
+    struct statvfs stat;
+    int r;
+
+    Py_BEGIN_ALLOW_THREADS;
+    r = statvfs(mounti->mount_path, &stat);
+    Py_END_ALLOW_THREADS;
+    if (r < 0) {
+        PyErr_SetFromErrnoWithFilename(PyExc_OSError, mounti->mount_path);
+        return -1;
+    }
+    mounti->frsize = stat.f_frsize;
+    mounti->total = stat.f_blocks;
+    mounti->bfree = stat.f_bfree;
+    mounti->bavail = stat.f_bavail;
+    mounti->files = stat.f_files;
+    mounti->ffree = stat.f_ffree;
+    mounti->favail = stat.f_favail;
+    mounti->frsize_status = PSI_STATUS_OK;
+    mounti->total_status = PSI_STATUS_OK;
+    mounti->bfree_status = PSI_STATUS_OK;
+    mounti->bavail_status = PSI_STATUS_OK;
+    mounti->files_status = PSI_STATUS_OK;
+    mounti->ffree_status = PSI_STATUS_OK;
+    mounti->favail_status = PSI_STATUS_OK;
+    return 0;
+}


Mime
View raw message