Deleted Added
full compact
33c33
< __FBSDID("$FreeBSD: head/sys/kern/kern_proc.c 185029 2008-11-17 20:49:29Z pjd $");
---
> __FBSDID("$FreeBSD: head/sys/kern/kern_proc.c 185548 2008-12-02 06:50:26Z peter $");
34a35
> #include "opt_compat.h"
1339a1341,1345
> #ifdef KINFO_OVMENTRY_SIZE
> CTASSERT(sizeof(struct kinfo_ovmentry) == KINFO_OVMENTRY_SIZE);
> #endif
>
> #ifdef COMPAT_FREEBSD7
1341c1347
< sysctl_kern_proc_vmmap(SYSCTL_HANDLER_ARGS)
---
> sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_ARGS)
1346c1352
< struct kinfo_vmentry *kve;
---
> struct kinfo_ovmentry *kve;
1499a1506
> #endif /* COMPAT_FREEBSD7 */
1500a1508,1676
> #ifdef KINFO_VMENTRY_SIZE
> CTASSERT(sizeof(struct kinfo_vmentry) == KINFO_VMENTRY_SIZE);
> #endif
>
> static int
> sysctl_kern_proc_vmmap(SYSCTL_HANDLER_ARGS)
> {
> vm_map_entry_t entry, tmp_entry;
> unsigned int last_timestamp;
> char *fullpath, *freepath;
> struct kinfo_vmentry *kve;
> struct vattr va;
> struct ucred *cred;
> int error, *name;
> struct vnode *vp;
> struct proc *p;
> vm_map_t map;
>
> name = (int *)arg1;
> if ((p = pfind((pid_t)name[0])) == NULL)
> return (ESRCH);
> if (p->p_flag & P_WEXIT) {
> PROC_UNLOCK(p);
> return (ESRCH);
> }
> if ((error = p_candebug(curthread, p))) {
> PROC_UNLOCK(p);
> return (error);
> }
> _PHOLD(p);
> PROC_UNLOCK(p);
>
> kve = malloc(sizeof(*kve), M_TEMP, M_WAITOK);
>
> map = &p->p_vmspace->vm_map; /* XXXRW: More locking required? */
> vm_map_lock_read(map);
> for (entry = map->header.next; entry != &map->header;
> entry = entry->next) {
> vm_object_t obj, tobj, lobj;
> vm_offset_t addr;
> int vfslocked;
>
> if (entry->eflags & MAP_ENTRY_IS_SUB_MAP)
> continue;
>
> bzero(kve, sizeof(*kve));
>
> kve->kve_private_resident = 0;
> obj = entry->object.vm_object;
> if (obj != NULL) {
> VM_OBJECT_LOCK(obj);
> if (obj->shadow_count == 1)
> kve->kve_private_resident =
> obj->resident_page_count;
> }
> kve->kve_resident = 0;
> addr = entry->start;
> while (addr < entry->end) {
> if (pmap_extract(map->pmap, addr))
> kve->kve_resident++;
> addr += PAGE_SIZE;
> }
>
> for (lobj = tobj = obj; tobj; tobj = tobj->backing_object) {
> if (tobj != obj)
> VM_OBJECT_LOCK(tobj);
> if (lobj != obj)
> VM_OBJECT_UNLOCK(lobj);
> lobj = tobj;
> }
>
> kve->kve_fileid = 0;
> kve->kve_fsid = 0;
> freepath = NULL;
> fullpath = "";
> if (lobj) {
> vp = NULL;
> switch(lobj->type) {
> case OBJT_DEFAULT:
> kve->kve_type = KVME_TYPE_DEFAULT;
> break;
> case OBJT_VNODE:
> kve->kve_type = KVME_TYPE_VNODE;
> vp = lobj->handle;
> vref(vp);
> break;
> case OBJT_SWAP:
> kve->kve_type = KVME_TYPE_SWAP;
> break;
> case OBJT_DEVICE:
> kve->kve_type = KVME_TYPE_DEVICE;
> break;
> case OBJT_PHYS:
> kve->kve_type = KVME_TYPE_PHYS;
> break;
> case OBJT_DEAD:
> kve->kve_type = KVME_TYPE_DEAD;
> break;
> default:
> kve->kve_type = KVME_TYPE_UNKNOWN;
> break;
> }
> if (lobj != obj)
> VM_OBJECT_UNLOCK(lobj);
>
> kve->kve_ref_count = obj->ref_count;
> kve->kve_shadow_count = obj->shadow_count;
> VM_OBJECT_UNLOCK(obj);
> if (vp != NULL) {
> vn_fullpath(curthread, vp, &fullpath,
> &freepath);
> cred = curthread->td_ucred;
> vfslocked = VFS_LOCK_GIANT(vp->v_mount);
> vn_lock(vp, LK_SHARED | LK_RETRY);
> if (VOP_GETATTR(vp, &va, cred) == 0) {
> kve->kve_fileid = va.va_fileid;
> kve->kve_fsid = va.va_fsid;
> }
> vput(vp);
> VFS_UNLOCK_GIANT(vfslocked);
> }
> } else {
> kve->kve_type = KVME_TYPE_NONE;
> kve->kve_ref_count = 0;
> kve->kve_shadow_count = 0;
> }
>
> kve->kve_start = entry->start;
> kve->kve_end = entry->end;
> kve->kve_offset = entry->offset;
>
> if (entry->protection & VM_PROT_READ)
> kve->kve_protection |= KVME_PROT_READ;
> if (entry->protection & VM_PROT_WRITE)
> kve->kve_protection |= KVME_PROT_WRITE;
> if (entry->protection & VM_PROT_EXECUTE)
> kve->kve_protection |= KVME_PROT_EXEC;
>
> if (entry->eflags & MAP_ENTRY_COW)
> kve->kve_flags |= KVME_FLAG_COW;
> if (entry->eflags & MAP_ENTRY_NEEDS_COPY)
> kve->kve_flags |= KVME_FLAG_NEEDS_COPY;
>
> strlcpy(kve->kve_path, fullpath, sizeof(kve->kve_path));
> if (freepath != NULL)
> free(freepath, M_TEMP);
>
> last_timestamp = map->timestamp;
> vm_map_unlock_read(map);
> /* Pack record size down */
> kve->kve_structsize = offsetof(struct kinfo_vmentry, kve_path) +
> strlen(kve->kve_path) + 1;
> kve->kve_structsize = roundup(kve->kve_structsize,
> sizeof(uint64_t));
> error = SYSCTL_OUT(req, kve, kve->kve_structsize);
> vm_map_lock_read(map);
> if (error)
> break;
> if (last_timestamp + 1 != map->timestamp) {
> vm_map_lookup_entry(map, addr - 1, &tmp_entry);
> entry = tmp_entry;
> }
> }
> vm_map_unlock_read(map);
> PRELE(p);
> free(kve, M_TEMP);
> return (error);
> }
>
1671a1848,1852
> #ifdef COMPAT_FREEBSD7
> static SYSCTL_NODE(_kern_proc, KERN_PROC_OVMMAP, ovmmap, CTLFLAG_RD,
> sysctl_kern_proc_ovmmap, "Old Process vm map entries");
> #endif
>