Author: trociny
Date: Sat Apr 20 07:47:26 2013
New Revision: 249666
URL: http://svnweb.freebsd.org/changeset/base/249666

Log:
  Make libprocstat(3) extract procstat notes from a process core file.
  
  PR:           kern/173723
  Suggested by: jhb
  Glanced by:   kib
  MFC after:    1 month

Added:
  head/lib/libprocstat/core.c   (contents, props changed)
  head/lib/libprocstat/core.h   (contents, props changed)
Modified:
  head/lib/libprocstat/Makefile
  head/lib/libprocstat/Symbol.map
  head/lib/libprocstat/libprocstat.3
  head/lib/libprocstat/libprocstat.c
  head/lib/libprocstat/libprocstat.h
  head/lib/libprocstat/libprocstat_internal.h

Modified: head/lib/libprocstat/Makefile
==============================================================================
--- head/lib/libprocstat/Makefile       Sat Apr 20 01:12:23 2013        
(r249665)
+++ head/lib/libprocstat/Makefile       Sat Apr 20 07:47:26 2013        
(r249666)
@@ -6,6 +6,7 @@ LIB=    procstat
 
 SRCS=  cd9660.c        \
        common_kvm.c    \
+       core.c          \
        libprocstat.c   \
         msdosfs.c      \
        udf.c
@@ -17,8 +18,8 @@ INCS=         libprocstat.h
 CFLAGS+=       -I. -I${.CURDIR} -D_KVM_VNODE
 SHLIB_MAJOR=   1
 
-DPADD=         ${LIBKVM} ${LIBUTIL}
-LDADD=         -lkvm -lutil
+DPADD=         ${LIBELF} ${LIBKVM} ${LIBUTIL}
+LDADD=         -lelf -lkvm -lutil
 
 MAN=           libprocstat.3
 

Modified: head/lib/libprocstat/Symbol.map
==============================================================================
--- head/lib/libprocstat/Symbol.map     Sat Apr 20 01:12:23 2013        
(r249665)
+++ head/lib/libprocstat/Symbol.map     Sat Apr 20 07:47:26 2013        
(r249666)
@@ -17,4 +17,5 @@ FBSD_1.2 {
 
 FBSD_1.3 {
        procstat_get_shm_info;
+       procstat_open_core;
 };

Added: head/lib/libprocstat/core.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/lib/libprocstat/core.c Sat Apr 20 07:47:26 2013        (r249666)
@@ -0,0 +1,262 @@
+/*-
+ * Copyright (c) 2013 Mikolaj Golub <troc...@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/elf.h>
+#include <sys/user.h>
+
+#include <assert.h>
+#include <err.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "core.h"
+
+#define PROCSTAT_CORE_MAGIC    0x012DADB8
+struct procstat_core
+{
+       int             pc_magic;
+       int             pc_fd;
+       Elf             *pc_elf;
+       GElf_Ehdr       pc_ehdr;
+       GElf_Phdr       pc_phdr;
+};
+
+static bool    core_offset(struct procstat_core *core, off_t offset);
+static bool    core_read(struct procstat_core *core, void *buf, size_t len);
+
+struct procstat_core *
+procstat_core_open(const char *filename)
+{
+       struct procstat_core *core;
+       Elf *e;
+       GElf_Ehdr ehdr;
+       GElf_Phdr phdr;
+       size_t nph;
+       int fd, i;
+
+       if (elf_version(EV_CURRENT) == EV_NONE) {
+               warnx("ELF library too old");
+               return (NULL);
+       }
+       fd = open(filename, O_RDONLY, 0);
+       if (fd == -1) {
+               warn("open(%s)", filename);
+               return (NULL);
+       }
+       e = elf_begin(fd, ELF_C_READ, NULL);
+       if (e == NULL) {
+               warnx("elf_begin: %s", elf_errmsg(-1));
+               goto fail;
+       }
+       if (elf_kind(e) != ELF_K_ELF) {
+               warnx("%s is not an ELF object", filename);
+               goto fail;
+       }
+       if (gelf_getehdr(e, &ehdr) == NULL) {
+               warnx("gelf_getehdr: %s", elf_errmsg(-1));
+               goto fail;
+       }
+       if (ehdr.e_type != ET_CORE) {
+               warnx("%s is not a CORE file", filename);
+               goto fail;
+       }
+       if (elf_getphnum(e, &nph) == 0) {
+               warnx("program headers not found");
+               goto fail;
+       }
+       for (i = 0; i < ehdr.e_phnum; i++) {
+               if (gelf_getphdr(e, i, &phdr) != &phdr) {
+                       warnx("gelf_getphdr: %s", elf_errmsg(-1));
+                       goto fail;
+               }
+               if (phdr.p_type == PT_NOTE)
+                       break;
+       }
+       if (i == ehdr.e_phnum) {
+               warnx("NOTE program header not found");
+               goto fail;
+       }
+       core = malloc(sizeof(struct procstat_core));
+       if (core == NULL) {
+               warn("malloc(%zu)", sizeof(struct procstat_core));
+               goto fail;
+       }
+       core->pc_magic = PROCSTAT_CORE_MAGIC;
+       core->pc_fd = fd;
+       core->pc_elf = e;
+       core->pc_ehdr = ehdr;
+       core->pc_phdr = phdr;
+
+       return (core);
+fail:
+       if (e != NULL)
+               elf_end(e);
+       close(fd);
+
+       return (NULL);
+}
+
+void
+procstat_core_close(struct procstat_core *core)
+{
+
+       assert(core->pc_magic == PROCSTAT_CORE_MAGIC);
+
+       elf_end(core->pc_elf);
+       close(core->pc_fd);
+       free(core);
+}
+
+void *
+procstat_core_get(struct procstat_core *core, enum psc_type type, void *buf,
+    size_t *lenp)
+{
+       Elf_Note nhdr;
+       off_t offset, eoffset;
+       void *freebuf;
+       size_t len;
+       u_int32_t n_type;
+       int cstructsize, structsize;
+       char nbuf[8];
+
+       assert(core->pc_magic == PROCSTAT_CORE_MAGIC);
+
+       switch(type) {
+       case PSC_TYPE_PROC:
+               n_type = NT_PROCSTAT_PROC;
+               structsize = sizeof(struct kinfo_proc);
+               break;
+       case PSC_TYPE_FILES:
+               n_type = NT_PROCSTAT_FILES;
+               structsize = sizeof(struct kinfo_file);
+               break;
+       case PSC_TYPE_VMMAP:
+               n_type = NT_PROCSTAT_VMMAP;
+               structsize = sizeof(struct kinfo_vmentry);
+               break;
+       default:
+               warnx("unknown core stat type: %d", type);
+               return (NULL);
+       }
+
+       offset = core->pc_phdr.p_offset;
+       eoffset = offset + core->pc_phdr.p_filesz;
+
+       while (offset < eoffset) {
+               if (!core_offset(core, offset))
+                       return (NULL);
+               if (!core_read(core, &nhdr, sizeof(nhdr)))
+                       return (NULL);
+
+               offset += sizeof(nhdr) +
+                   roundup2(nhdr.n_namesz, sizeof(Elf32_Size)) +
+                   roundup2(nhdr.n_descsz, sizeof(Elf32_Size));
+
+               if (nhdr.n_namesz == 0 && nhdr.n_descsz == 0)
+                       break;
+               if (nhdr.n_type != n_type)
+                       continue;
+               if (nhdr.n_namesz != 8)
+                       continue;
+               if (!core_read(core, nbuf, sizeof(nbuf)))
+                       return (NULL);
+               if (strcmp(nbuf, "FreeBSD") != 0)
+                       continue;
+               if (nhdr.n_descsz < sizeof(cstructsize)) {
+                       warnx("corrupted core file");
+                       return (NULL);
+               }
+               if (!core_read(core, &cstructsize, sizeof(cstructsize)))
+                       return (NULL);
+               if (cstructsize != structsize) {
+                       warnx("version mismatch");
+                       return (NULL);
+               }
+               len = nhdr.n_descsz - sizeof(cstructsize);
+               if (len == 0)
+                       return (NULL);
+               if (buf != NULL) {
+                       len = MIN(len, *lenp);
+                       freebuf = NULL;
+               } else {
+                       freebuf = buf = malloc(len);
+                       if (buf == NULL) {
+                               warn("malloc(%zu)", len);
+                               return (NULL);
+                       }
+               }
+               if (!core_read(core, buf, len)) {
+                       free(freebuf);
+                       return (NULL);
+               }
+               *lenp = len;
+               return (buf);
+        }
+
+       return (NULL);
+}
+
+static bool
+core_offset(struct procstat_core *core, off_t offset)
+{
+
+       assert(core->pc_magic == PROCSTAT_CORE_MAGIC);
+
+       if (lseek(core->pc_fd, offset, SEEK_SET) == -1) {
+               warn("core: lseek(%jd)", (intmax_t)offset);
+               return (false);
+       }
+       return (true);
+}
+
+static bool
+core_read(struct procstat_core *core, void *buf, size_t len)
+{
+       ssize_t n;
+
+       assert(core->pc_magic == PROCSTAT_CORE_MAGIC);
+
+       n = read(core->pc_fd, buf, len);
+       if (n == -1) {
+               warn("core: read");
+               return (false);
+       }
+       if (n < (ssize_t)len) {
+               warnx("core: short read");
+               return (false);
+       }
+       return (true);
+}

Added: head/lib/libprocstat/core.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/lib/libprocstat/core.h Sat Apr 20 07:47:26 2013        (r249666)
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2013 Mikolaj Golub <troc...@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _CORE_H
+#define _CORE_H
+
+enum psc_type {
+       PSC_TYPE_PROC,
+       PSC_TYPE_FILES,
+       PSC_TYPE_VMMAP,
+};
+
+struct procstat_core;
+
+void procstat_core_close(struct procstat_core *core);
+void *procstat_core_get(struct procstat_core *core, enum psc_type type,
+    void * buf, size_t *lenp);
+struct procstat_core *procstat_core_open(const char *filename);
+
+#endif         /* !_CORE_H_ */

Modified: head/lib/libprocstat/libprocstat.3
==============================================================================
--- head/lib/libprocstat/libprocstat.3  Sat Apr 20 01:12:23 2013        
(r249665)
+++ head/lib/libprocstat/libprocstat.3  Sat Apr 20 07:47:26 2013        
(r249666)
@@ -28,6 +28,7 @@
 .Dt LIBPROCSTAT 3
 .Os
 .Sh NAME
+.Nm procstat_open_core ,
 .Nm procstat_open_kvm ,
 .Nm procstat_open_sysctl ,
 .Nm procstat_close ,
@@ -105,6 +106,8 @@
 .Fa "unsigned int *count"
 .Fc
 .Ft "struct procstat *"
+.Fn procstat_open_core "const char *filename"
+.Ft "struct procstat *"
 .Fn procstat_open_kvm "const char *nlistf" "const char *memf"
 .Ft "struct procstat *"
 .Fn procstat_open_sysctl void
@@ -116,7 +119,11 @@ retrieval from the running kernel via th
 .Xr sysctl 3
 library backend, and for post-mortem analysis via the
 .Xr kvm 3
-library backend.
+library backend, or from the process
+.Xr core 5
+file, searching for statistics in special
+.Xr elf 3
+note sections.
 .Pp
 The
 .Fn procstat_open_kvm
@@ -129,6 +136,16 @@ or
 library routines, respectively, to access kernel state information
 used to retrieve processes and files states.
 The
+.Fn procstat_open_core
+uses
+.Xr elf 3
+routines to access statistics stored as a set of notes in a process
+.Xr core 5
+file, written by the kernel at the moment of the process abnormal termination.
+The
+.Fa filename
+argument is the process core file name.
+The
 .Fa nlistf
 argument is the executable image of the kernel being examined.
 If this argument is
@@ -145,7 +162,7 @@ is assumed.
 See
 .Xr kvm_open 3
 for more details.
-Both functions dynamically allocate and return a
+The functions dynamically allocate and return a
 .Vt procstat
 structure pointer used in the rest of the
 .Nm libprocstat
@@ -250,10 +267,12 @@ argument indicates an actual error messa
 .Xr pipe 2 ,
 .Xr shm_open 2 ,
 .Xr socket 2 ,
+.Xr elf 3 ,
 .Xr kvm 3 ,
 .Xr queue 3 ,
 .Xr sysctl 3 ,
 .Xr pts 4 ,
+.Xr core 5 ,
 .Xr vnode 9
 .Sh HISTORY
 The

Modified: head/lib/libprocstat/libprocstat.c
==============================================================================
--- head/lib/libprocstat/libprocstat.c  Sat Apr 20 01:12:23 2013        
(r249665)
+++ head/lib/libprocstat/libprocstat.c  Sat Apr 20 07:47:26 2013        
(r249666)
@@ -96,11 +96,13 @@ __FBSDID("$FreeBSD$");
 #include <libprocstat.h>
 #include "libprocstat_internal.h"
 #include "common_kvm.h"
+#include "core.h"
 
 int     statfs(const char *, struct statfs *); /* XXX */
 
 #define        PROCSTAT_KVM    1
 #define        PROCSTAT_SYSCTL 2
+#define        PROCSTAT_CORE   3
 
 static char    *getmnton(kvm_t *kd, struct mount *m);
 static struct filestat_list    *procstat_getfiles_kvm(
@@ -137,6 +139,8 @@ procstat_close(struct procstat *procstat
        assert(procstat);
        if (procstat->type == PROCSTAT_KVM)
                kvm_close(procstat->kd);
+       else if (procstat->type == PROCSTAT_CORE)
+               procstat_core_close(procstat->core);
        free(procstat);
 }
 
@@ -177,6 +181,27 @@ procstat_open_kvm(const char *nlistf, co
        return (procstat);
 }
 
+struct procstat *
+procstat_open_core(const char *filename)
+{
+       struct procstat *procstat;
+       struct procstat_core *core;
+
+       procstat = calloc(1, sizeof(*procstat));
+       if (procstat == NULL) {
+               warn("malloc()");
+               return (NULL);
+       }
+       core = procstat_core_open(filename);
+       if (core == NULL) {
+               free(procstat);
+               return (NULL);
+       }
+       procstat->type = PROCSTAT_CORE;
+       procstat->core = core;
+       return (procstat);
+}
+
 struct kinfo_proc *
 procstat_getprocs(struct procstat *procstat, int what, int arg,
     unsigned int *count)
@@ -231,6 +256,15 @@ procstat_getprocs(struct procstat *procs
                }
                /* Perform simple consistency checks. */
                if ((len % sizeof(*p)) != 0 || p->ki_structsize != sizeof(*p)) {
+                       warnx("kinfo_proc structure size mismatch (len = %zu)", 
len);
+                       goto fail;
+               }
+               *count = len / sizeof(*p);
+               return (p);
+       } else if (procstat->type == PROCSTAT_CORE) {
+               p = procstat_core_get(procstat->core, PSC_TYPE_PROC, NULL,
+                   &len);
+               if ((len % sizeof(*p)) != 0 || p->ki_structsize != sizeof(*p)) {
                        warnx("kinfo_proc structure size mismatch");
                        goto fail;
                }
@@ -258,13 +292,17 @@ procstat_freeprocs(struct procstat *proc
 struct filestat_list *
 procstat_getfiles(struct procstat *procstat, struct kinfo_proc *kp, int 
mmapped)
 {
-       
-       if (procstat->type == PROCSTAT_SYSCTL)
-               return (procstat_getfiles_sysctl(procstat, kp, mmapped));
-       else if (procstat->type == PROCSTAT_KVM)
+
+       switch(procstat->type) {
+       case PROCSTAT_KVM:
                return (procstat_getfiles_kvm(procstat, kp, mmapped));
-       else
+       case PROCSTAT_SYSCTL:
+       case PROCSTAT_CORE:
+               return (procstat_getfiles_sysctl(procstat, kp, mmapped));
+       default:
+               warnx("unknown access method: %d", procstat->type);
                return (NULL);
+       }
 }
 
 void
@@ -646,8 +684,62 @@ kinfo_uflags2fst(int fd)
        return (0);
 }
 
+static struct kinfo_file *
+kinfo_getfile_core(struct procstat_core *core, int *cntp)
+{
+       int cnt;
+       size_t len;
+       char *buf, *bp, *eb;
+       struct kinfo_file *kif, *kp, *kf;
+
+       buf = procstat_core_get(core, PSC_TYPE_FILES, NULL, &len);
+       if (buf == NULL)
+               return (NULL);
+       /*
+        * XXXMG: The code below is just copy&past from libutil.
+        * The code duplication can be avoided if libutil
+        * is extended to provide something like:
+        *   struct kinfo_file *kinfo_getfile_from_buf(const char *buf,
+        *       size_t len, int *cntp);
+        */
+
+       /* Pass 1: count items */
+       cnt = 0;
+       bp = buf;
+       eb = buf + len;
+       while (bp < eb) {
+               kf = (struct kinfo_file *)(uintptr_t)bp;
+               bp += kf->kf_structsize;
+               cnt++;
+       }
+
+       kif = calloc(cnt, sizeof(*kif));
+       if (kif == NULL) {
+               free(buf);
+               return (NULL);
+       }
+       bp = buf;
+       eb = buf + len;
+       kp = kif;
+       /* Pass 2: unpack */
+       while (bp < eb) {
+               kf = (struct kinfo_file *)(uintptr_t)bp;
+               /* Copy/expand into pre-zeroed buffer */
+               memcpy(kp, kf, kf->kf_structsize);
+               /* Advance to next packed record */
+               bp += kf->kf_structsize;
+               /* Set field size to fixed length, advance */
+               kp->kf_structsize = sizeof(*kp);
+               kp++;
+       }
+       free(buf);
+       *cntp = cnt;
+       return (kif);   /* Caller must free() return value */
+}
+
 static struct filestat_list *
-procstat_getfiles_sysctl(struct procstat *procstat, struct kinfo_proc *kp, int 
mmapped)
+procstat_getfiles_sysctl(struct procstat *procstat, struct kinfo_proc *kp,
+    int mmapped)
 {
        struct kinfo_file *kif, *files;
        struct kinfo_vmentry *kve, *vmentries;
@@ -663,8 +755,16 @@ procstat_getfiles_sysctl(struct procstat
        assert(kp);
        if (kp->ki_fd == NULL)
                return (NULL);
-
-       files = kinfo_getfile(kp->ki_pid, &cnt);
+       switch(procstat->type) {
+       case PROCSTAT_SYSCTL:
+               files = kinfo_getfile(kp->ki_pid, &cnt);
+               break;
+       case PROCSTAT_CORE:
+               files = kinfo_getfile_core(procstat->core, &cnt);
+               break;
+       default:
+               assert(!"invalid type");
+       }
        if (files == NULL && errno != EPERM) {
                warn("kinfo_getfile()");
                return (NULL);
@@ -742,7 +842,8 @@ procstat_get_pipe_info(struct procstat *
        if (procstat->type == PROCSTAT_KVM) {
                return (procstat_get_pipe_info_kvm(procstat->kd, fst, ps,
                    errbuf));
-       } else if (procstat->type == PROCSTAT_SYSCTL) {
+       } else if (procstat->type == PROCSTAT_SYSCTL ||
+               procstat->type == PROCSTAT_CORE) {
                return (procstat_get_pipe_info_sysctl(fst, ps, errbuf));
        } else {
                warnx("unknown access method: %d", procstat->type);
@@ -806,7 +907,8 @@ procstat_get_pts_info(struct procstat *p
        if (procstat->type == PROCSTAT_KVM) {
                return (procstat_get_pts_info_kvm(procstat->kd, fst, pts,
                    errbuf));
-       } else if (procstat->type == PROCSTAT_SYSCTL) {
+       } else if (procstat->type == PROCSTAT_SYSCTL ||
+               procstat->type == PROCSTAT_CORE) {
                return (procstat_get_pts_info_sysctl(fst, pts, errbuf));
        } else {
                warnx("unknown access method: %d", procstat->type);
@@ -868,7 +970,8 @@ procstat_get_shm_info(struct procstat *p
        if (procstat->type == PROCSTAT_KVM) {
                return (procstat_get_shm_info_kvm(procstat->kd, fst, shm,
                    errbuf));
-       } else if (procstat->type == PROCSTAT_SYSCTL) {
+       } else if (procstat->type == PROCSTAT_SYSCTL ||
+           procstat->type == PROCSTAT_CORE) {
                return (procstat_get_shm_info_sysctl(fst, shm, errbuf));
        } else {
                warnx("unknown access method: %d", procstat->type);
@@ -948,7 +1051,8 @@ procstat_get_vnode_info(struct procstat 
        if (procstat->type == PROCSTAT_KVM) {
                return (procstat_get_vnode_info_kvm(procstat->kd, fst, vn,
                    errbuf));
-       } else if (procstat->type == PROCSTAT_SYSCTL) {
+       } else if (procstat->type == PROCSTAT_SYSCTL ||
+               procstat->type == PROCSTAT_CORE) {
                return (procstat_get_vnode_info_sysctl(fst, vn, errbuf));
        } else {
                warnx("unknown access method: %d", procstat->type);
@@ -1150,7 +1254,8 @@ procstat_get_socket_info(struct procstat
        if (procstat->type == PROCSTAT_KVM) {
                return (procstat_get_socket_info_kvm(procstat->kd, fst, sock,
                    errbuf));
-       } else if (procstat->type == PROCSTAT_SYSCTL) {
+       } else if (procstat->type == PROCSTAT_SYSCTL ||
+               procstat->type == PROCSTAT_CORE) {
                return (procstat_get_socket_info_sysctl(fst, sock, errbuf));
        } else {
                warnx("unknown access method: %d", procstat->type);
@@ -1401,3 +1506,4 @@ getmnton(kvm_t *kd, struct mount *m)
        mhead = mt;
        return (mt->mntonname);
 }
+

Modified: head/lib/libprocstat/libprocstat.h
==============================================================================
--- head/lib/libprocstat/libprocstat.h  Sat Apr 20 01:12:23 2013        
(r249665)
+++ head/lib/libprocstat/libprocstat.h  Sat Apr 20 07:47:26 2013        
(r249666)
@@ -162,6 +162,7 @@ int procstat_get_socket_info(struct proc
     struct sockstat *sock, char *errbuf);
 int    procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst,
     struct vnstat *vn, char *errbuf);
+struct procstat        *procstat_open_core(const char *filename);
 struct procstat        *procstat_open_sysctl(void);
 struct procstat        *procstat_open_kvm(const char *nlistf, const char 
*memf);
 __END_DECLS

Modified: head/lib/libprocstat/libprocstat_internal.h
==============================================================================
--- head/lib/libprocstat/libprocstat_internal.h Sat Apr 20 01:12:23 2013        
(r249665)
+++ head/lib/libprocstat/libprocstat_internal.h Sat Apr 20 07:47:26 2013        
(r249666)
@@ -34,6 +34,7 @@ struct procstat {
        kvm_t   *kd;
        void    *vmentries;
        void    *files;
+       struct procstat_core *core;
 };
 
 #endif /* !_LIBPROCSTAT_INTERNAL_H_ */
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to