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