diff options
author | Jasper Lievisse Adriaanse <jasper@humppa.nl> | 2011-06-16 13:03:24 +0200 |
---|---|---|
committer | Jasper Lievisse Adriaanse <jasper@humppa.nl> | 2011-06-16 13:03:24 +0200 |
commit | 15ffb2d039b43f1bd73f766741c11d8e7d2905d0 (patch) | |
tree | b273a43308ec997b3c8b73e45f1e6581417fba8a /sysdeps/openbsd | |
parent | 7f14f4409d94a89322aa1d20aacdae1703100893 (diff) | |
download | libgtop-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.c | 154 |
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); |