From owner-svn-src-all@FreeBSD.ORG Sat Apr 20 07:49:37 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 2427C84F; Sat, 20 Apr 2013 07:49:37 +0000 (UTC) (envelope-from trociny@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 16746119E; Sat, 20 Apr 2013 07:49:37 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r3K7naIG086864; Sat, 20 Apr 2013 07:49:36 GMT (envelope-from trociny@svn.freebsd.org) Received: (from trociny@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r3K7nacZ086850; Sat, 20 Apr 2013 07:49:36 GMT (envelope-from trociny@svn.freebsd.org) Message-Id: <201304200749.r3K7nacZ086850@svn.freebsd.org> From: Mikolaj Golub Date: Sat, 20 Apr 2013 07:49:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r249667 - head/lib/libprocstat X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Apr 2013 07:49:37 -0000 Author: trociny Date: Sat Apr 20 07:49:35 2013 New Revision: 249667 URL: http://svnweb.freebsd.org/changeset/base/249667 Log: Add procstat_getvmmap function to get VM layout of a process. MFC after: 1 month Modified: head/lib/libprocstat/Symbol.map head/lib/libprocstat/libprocstat.3 head/lib/libprocstat/libprocstat.c head/lib/libprocstat/libprocstat.h Modified: head/lib/libprocstat/Symbol.map ============================================================================== --- head/lib/libprocstat/Symbol.map Sat Apr 20 07:47:26 2013 (r249666) +++ head/lib/libprocstat/Symbol.map Sat Apr 20 07:49:35 2013 (r249667) @@ -16,6 +16,8 @@ FBSD_1.2 { }; FBSD_1.3 { + procstat_freevmmap; procstat_get_shm_info; + procstat_getvmmap; procstat_open_core; }; Modified: head/lib/libprocstat/libprocstat.3 ============================================================================== --- head/lib/libprocstat/libprocstat.3 Sat Apr 20 07:47:26 2013 (r249666) +++ head/lib/libprocstat/libprocstat.3 Sat Apr 20 07:49:35 2013 (r249667) @@ -34,8 +34,10 @@ .Nm procstat_close , .Nm procstat_getfiles , .Nm procstat_getprocs , +.Nm procstat_getvmmap , .Nm procstat_freefiles , .Nm procstat_freeprocs , +.Nm procstat_freevmmap , .Nm procstat_get_pipe_info , .Nm procstat_get_pts_info , .Nm procstat_get_shm_info , @@ -57,6 +59,11 @@ .Fc .Ft void .Fn procstat_freeprocs "struct procstat *procstat" "struct kinfo_proc *p" +.Ft void +.Fo procstat_freevmmap +.Fa "struct procstat *procstat" +.Fa "struct kinfo_vmentry *vmmap" +.Fc .Ft int .Fo procstat_get_pipe_info .Fa "struct procstat *procstat" @@ -105,6 +112,12 @@ .Fa "int arg" .Fa "unsigned int *count" .Fc +.Ft "struct kinfo_vmentry *" +.Fo procstat_getvmmap +.Fa "struct procstat *procstat" +.Fa "struct kinfo_proc *kp" +.Fa "unsigned int *count" +.Fc .Ft "struct procstat *" .Fn procstat_open_core "const char *filename" .Ft "struct procstat *" @@ -214,6 +227,22 @@ The caller is responsible to free the al function call. .Pp The +.Fn procstat_getvmmap +function gets a pointer to the +.Vt procstat +structure initialized with one of the +.Fn procstat_open_* +functions, a pointer to +.Vt kinfo_proc +structure, and returns VM layout of the process as a dynamically allocated +array of +.Vt kinfo_vmentry +structures. +The caller is responsible to free the allocated memory with a subsequent +.Fn procstat_freevmmap +function call. +.Pp +The .Fn procstat_get_pipe_info , .Fn procstat_get_pts_info , .Fn procstat_get_shm_info , Modified: head/lib/libprocstat/libprocstat.c ============================================================================== --- head/lib/libprocstat/libprocstat.c Sat Apr 20 07:47:26 2013 (r249666) +++ head/lib/libprocstat/libprocstat.c Sat Apr 20 07:49:35 2013 (r249667) @@ -105,6 +105,8 @@ int statfs(const char *, struct stat #define PROCSTAT_CORE 3 static char *getmnton(kvm_t *kd, struct mount *m); +static struct kinfo_vmentry * kinfo_getvmmap_core(struct procstat_core *core, + int *cntp); static struct filestat_list *procstat_getfiles_kvm( struct procstat *procstat, struct kinfo_proc *kp, int mmapped); static struct filestat_list *procstat_getfiles_sysctl( @@ -802,7 +804,7 @@ procstat_getfiles_sysctl(struct procstat STAILQ_INSERT_TAIL(head, entry, next); } if (mmapped != 0) { - vmentries = kinfo_getvmmap(kp->ki_pid, &cnt); + vmentries = procstat_getvmmap(procstat, kp, &cnt); procstat->vmentries = vmentries; if (vmentries == NULL || cnt == 0) goto fail; @@ -1507,3 +1509,82 @@ getmnton(kvm_t *kd, struct mount *m) return (mt->mntonname); } +static struct kinfo_vmentry * +kinfo_getvmmap_core(struct procstat_core *core, int *cntp) +{ + int cnt; + size_t len; + char *buf, *bp, *eb; + struct kinfo_vmentry *kiv, *kp, *kv; + + buf = procstat_core_get(core, PSC_TYPE_VMMAP, 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_vmentry *kinfo_getvmmap_from_buf(const char *buf, + * size_t len, int *cntp); + */ + + /* Pass 1: count items */ + cnt = 0; + bp = buf; + eb = buf + len; + while (bp < eb) { + kv = (struct kinfo_vmentry *)(uintptr_t)bp; + bp += kv->kve_structsize; + cnt++; + } + + kiv = calloc(cnt, sizeof(*kiv)); + if (kiv == NULL) { + free(buf); + return (NULL); + } + bp = buf; + eb = buf + len; + kp = kiv; + /* Pass 2: unpack */ + while (bp < eb) { + kv = (struct kinfo_vmentry *)(uintptr_t)bp; + /* Copy/expand into pre-zeroed buffer */ + memcpy(kp, kv, kv->kve_structsize); + /* Advance to next packed record */ + bp += kv->kve_structsize; + /* Set field size to fixed length, advance */ + kp->kve_structsize = sizeof(*kp); + kp++; + } + free(buf); + *cntp = cnt; + return (kiv); /* Caller must free() return value */ +} + +struct kinfo_vmentry * +procstat_getvmmap(struct procstat *procstat, struct kinfo_proc *kp, + unsigned int *cntp) +{ + switch(procstat->type) { + case PROCSTAT_KVM: + warnx("kvm method is not supported"); + return (NULL); + case PROCSTAT_SYSCTL: + return (kinfo_getvmmap(kp->ki_pid, cntp)); + case PROCSTAT_CORE: + return (kinfo_getvmmap_core(procstat->core, cntp)); + default: + warnx("unknown access method: %d", procstat->type); + return (NULL); + } +} + +void +procstat_freevmmap(struct procstat *procstat __unused, + struct kinfo_vmentry *vmmap) +{ + + free(vmmap); +} Modified: head/lib/libprocstat/libprocstat.h ============================================================================== --- head/lib/libprocstat/libprocstat.h Sat Apr 20 07:47:26 2013 (r249666) +++ head/lib/libprocstat/libprocstat.h Sat Apr 20 07:49:35 2013 (r249667) @@ -89,6 +89,7 @@ #define PS_FST_FFLAG_EXEC 0x2000 #define PS_FST_FFLAG_HASLOCK 0x4000 +struct kinfo_vmentry; struct procstat; struct filestat { int fs_type; /* Descriptor type. */ @@ -148,6 +149,8 @@ void procstat_close(struct procstat *pro void procstat_freeprocs(struct procstat *procstat, struct kinfo_proc *p); void procstat_freefiles(struct procstat *procstat, struct filestat_list *head); +void procstat_freevmmap(struct procstat *procstat, + struct kinfo_vmentry *vmmap); struct filestat_list *procstat_getfiles(struct procstat *procstat, struct kinfo_proc *kp, int mmapped); struct kinfo_proc *procstat_getprocs(struct procstat *procstat, @@ -162,6 +165,8 @@ 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 kinfo_vmentry *procstat_getvmmap(struct procstat *procstat, + struct kinfo_proc *kp, unsigned int *count); 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);