svn commit: r249666 - head/lib/libprocstat

Mikolaj Golub trociny at FreeBSD.org
Sat Apr 20 07:47:28 UTC 2013


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 <trociny at 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 <trociny at 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_ */


More information about the svn-src-all mailing list