summaryrefslogtreecommitdiff
path: root/sysdeps/openbsd
diff options
context:
space:
mode:
authorJasper Lievisse Adriaanse <jasper@humppa.nl>2011-06-16 13:03:24 +0200
committerJasper Lievisse Adriaanse <jasper@humppa.nl>2011-06-16 13:03:24 +0200
commit15ffb2d039b43f1bd73f766741c11d8e7d2905d0 (patch)
treeb273a43308ec997b3c8b73e45f1e6581417fba8a /sysdeps/openbsd
parent7f14f4409d94a89322aa1d20aacdae1703100893 (diff)
downloadlibgtop-15ffb2d039b43f1bd73f766741c11d8e7d2905d0.tar.gz
Revert vmmap-based procmap.c for OpenBSD.
vmmap was reverted in OpenBSD, so stick to the old algorithm for now.
Diffstat (limited to 'sysdeps/openbsd')
-rw-r--r--sysdeps/openbsd/procmap.c154
1 files changed, 30 insertions, 124 deletions
diff --git a/sysdeps/openbsd/procmap.c b/sysdeps/openbsd/procmap.c
index acbd0fda..037ca1f7 100644
--- a/sysdeps/openbsd/procmap.c
+++ b/sysdeps/openbsd/procmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: procmap.c,v 1.4 2011/05/26 17:47:25 jasper Exp $ */
+/* $OpenBSD: procmap.c,v 1.6 2011/06/06 17:12:12 jasper Exp $ */
/* Copyright (C) 1998 Joshua Sled
This file is part of LibGTop 1.0.
@@ -29,7 +29,6 @@
#include <glibtop_suid.h>
#include <kvm.h>
-#include <stdlib.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/resource.h>
@@ -57,12 +56,6 @@ static const unsigned long _glibtop_sysdeps_map_entry =
(1L << GLIBTOP_MAP_ENTRY_OFFSET) + (1L << GLIBTOP_MAP_ENTRY_PERM) +
(1L << GLIBTOP_MAP_ENTRY_INODE) + (1L << GLIBTOP_MAP_ENTRY_DEVICE);
-/* Local helper functions. */
-
-ssize_t load_vmmap_entries(glibtop*, unsigned long, struct vm_map_entry**,
- struct vm_map_entry*);
-void unload_vmmap_entries(struct vm_map_entry *);
-
/* Init function. */
void
@@ -71,86 +64,6 @@ _glibtop_init_proc_map_p (glibtop *server)
server->sysdeps.proc_map = _glibtop_sysdeps_proc_map;
}
-/*
- * Download vmmap_entries from the kernel into our address space.
- * We fix up the addr tree while downloading.
- *
- * Returns: the size of the tree on succes, or -1 on failure.
- * On failure, *rptr needs to be passed to unload_vmmap_entries to free
- * the lot.
- */
-ssize_t
-load_vmmap_entries(glibtop *server, unsigned long kptr,
- struct vm_map_entry **rptr, struct vm_map_entry *parent)
-{
- struct vm_map_entry *entry;
- unsigned long left_kptr, right_kptr;
- ssize_t left_sz;
- ssize_t right_sz;
-
- if (kptr == 0)
- return 0;
-
- /* Need space. */
- entry = malloc(sizeof(*entry));
- if (entry == NULL)
- return -1;
-
- /* Download entry at kptr. */
- if (kvm_read (server->machine.kd, kptr,
- (char *)entry, sizeof(*entry)) != sizeof(*entry)) {
- free(entry);
- return -1;
- }
-
- /*
- * Update addr pointers to have sane values in this address space.
- * We save the kernel pointers in {left,right}_kptr, so we have them
- * available to download children.
- */
- left_kptr = (unsigned long) RB_LEFT(entry, daddrs.addr_entry);
- right_kptr = (unsigned long) RB_RIGHT(entry, daddrs.addr_entry);
- RB_LEFT(entry, daddrs.addr_entry) =
- RB_RIGHT(entry, daddrs.addr_entry) = NULL;
- /* Fill in parent pointer. */
- RB_PARENT(entry, daddrs.addr_entry) = parent;
-
- /*
- * Consistent state reached, fill in *rptr.
- */
- *rptr = entry;
-
- /*
- * Download left, right.
- * On failure, our map is in a state that can be handled by
- * unload_vmmap_entries.
- */
- left_sz = load_vmmap_entries(server, left_kptr,
- &RB_LEFT(entry, daddrs.addr_entry), entry);
- if (left_sz == -1)
- return -1;
- right_sz = load_vmmap_entries(server, right_kptr,
- &RB_RIGHT(entry, daddrs.addr_entry), entry);
- if (right_sz == -1)
- return -1;
-
- return 1 + left_sz + right_sz;
-}
-
-/*
- * Free the vmmap entries in the given tree.
- */
-void
-unload_vmmap_entries(struct vm_map_entry *entry)
-{
- if (entry == NULL)
- return;
-
- unload_vmmap_entries(RB_LEFT(entry, daddrs.addr_entry));
- unload_vmmap_entries(RB_RIGHT(entry, daddrs.addr_entry));
- free(entry);
-}
-
/* Provides detailed information about a process. */
glibtop_map_entry *
@@ -158,16 +71,15 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
pid_t pid)
{
struct kinfo_proc2 *pinfo;
- struct vm_map_entry *entry;
- struct uvm_map_addr root;
+ struct vm_map_entry entry, *first;
struct vmspace vmspace;
struct vnode vnode;
struct inode inode;
- ssize_t nentries;
GArray *maps = g_array_sized_new(FALSE, FALSE,
sizeof(glibtop_map_entry),
100);
int count, i = 0;
+ int update = 0;
glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_MAP), 0);
@@ -192,18 +104,16 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
(char *) &vmspace, sizeof (vmspace)) != sizeof (vmspace))
glibtop_error_io_r (server, "kvm_read (vmspace)");
- RB_INIT(&root);
- nentries = load_vmmap_entries(server,
- (unsigned long) RB_ROOT(&vmspace.vm_map.addr),
- &RB_ROOT(&root), NULL);
- if (nentries == -1) {
- unload_vmmap_entries(RB_ROOT(&root));
+ first = vmspace.vm_map.header.next;
+
+ if (kvm_read (server->machine.kd,
+ (unsigned long) vmspace.vm_map.header.next,
+ (char *) &entry, sizeof (entry)) != sizeof (entry))
glibtop_error_io_r (server, "kvm_read (entry)");
- }
/* Allocate space. */
- buf->number = nentries;
+ buf->number = vmspace.vm_map.nentries;
buf->size = sizeof (glibtop_map_entry);
buf->total = buf->number * buf->size;
@@ -216,23 +126,32 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
* to the mmap'ed area, the object type changes from OBJT_VNODE
* to OBJT_DEFAULT so it seems this really works. */
- RB_FOREACH(entry, uvm_map_addr, &root) {
+ do {
glibtop_map_entry *mentry;
unsigned long inum, dev;
guint len;
- if (UVM_ET_ISSUBMAP(entry))
+ if (update) {
+ if (kvm_read (server->machine.kd,
+ (unsigned long) entry.next,
+ &entry, sizeof (entry)) != sizeof (entry))
+ glibtop_error_io_r (server, "kvm_read (entry)");
+ } else {
+ update = 1;
+ }
+
+ if (UVM_ET_ISSUBMAP (&entry))
continue;
- if (!entry->object.uvm_obj)
+
+ if (!entry.object.uvm_obj)
continue;
/* We're only interested in vnodes */
if (kvm_read (server->machine.kd,
- (unsigned long) entry->object.uvm_obj,
+ (unsigned long) entry.object.uvm_obj,
&vnode, sizeof (vnode)) != sizeof (vnode)) {
glibtop_warn_io_r (server, "kvm_read (vnode)");
- unload_vmmap_entries(RB_ROOT(&root));
return (glibtop_map_entry*) g_array_free(maps, TRUE);
}
@@ -257,21 +176,21 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
mentry->flags = _glibtop_sysdeps_map_entry;
- mentry->start = (guint64) entry->start;
- mentry->end = (guint64) entry->end;
- mentry->offset = (guint64) entry->offset;
+ mentry->start = (guint64) entry.start;
+ mentry->end = (guint64) entry.end;
+ mentry->offset = (guint64) entry.offset;
mentry->device = (guint64) dev;
mentry->inode = (guint64) inum;
mentry->perm = (guint64) 0;
- if (entry->protection & VM_PROT_READ)
+ if (entry.protection & VM_PROT_READ)
mentry->perm |= GLIBTOP_MAP_PERM_READ;
- if (entry->protection & VM_PROT_WRITE)
+ if (entry.protection & VM_PROT_WRITE)
mentry->perm |= GLIBTOP_MAP_PERM_WRITE;
- if (entry->protection & VM_PROT_EXECUTE)
+ if (entry.protection & VM_PROT_EXECUTE)
mentry->perm |= GLIBTOP_MAP_PERM_EXECUTE;
- }
+ } while (entry.next != first);
buf->flags = _glibtop_sysdeps_proc_map;
@@ -279,18 +198,5 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
buf->size = sizeof (glibtop_map_entry);
buf->total = buf->number * buf->size;
- unload_vmmap_entries(RB_ROOT(&root));
return (glibtop_map_entry*) g_array_free(maps, FALSE);
}
-
-/*
- * Don't implement address comparison.
- */
-static __inline int
-no_impl(void *p, void *q)
-{
- abort(); /* Should not be called. */
- return 0;
-}
-
-RB_GENERATE(uvm_map_addr, vm_map_entry, daddrs.addr_entry, no_impl);