diff options
author | peter <peter@FreeBSD.org> | 2008-12-01 02:13:32 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2008-12-01 02:13:32 +0000 |
commit | cd7b78c33f9eb6fc2730afe6d09252f28cf9996e (patch) | |
tree | e963253100025189e4677453dce1ce6366c165c0 | |
parent | 6c7a0d64c96e8f0c9db396ce39bc593787ff794f (diff) | |
download | FreeBSD-src-cd7b78c33f9eb6fc2730afe6d09252f28cf9996e.zip FreeBSD-src-cd7b78c33f9eb6fc2730afe6d09252f28cf9996e.tar.gz |
Duplicate another few hundred lines of code in order to be compatible
with unreleased binaries.
-rw-r--r-- | sys/kern/kern_descrip.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_proc.c | 181 | ||||
-rw-r--r-- | sys/sys/sysctl.h | 6 | ||||
-rw-r--r-- | sys/sys/user.h | 26 |
4 files changed, 211 insertions, 4 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 11fa1c2..faac641 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -2806,6 +2806,7 @@ export_vnode_for_sysctl(struct vnode *vp, int type, strlcpy(kif->kf_path, fullpath, sizeof(kif->kf_path)); if (freepath != NULL) free(freepath, M_TEMP); + /* Pack record size down */ kif->kf_structsize = offsetof(struct kinfo_file, kf_path) + strlen(kif->kf_path) + 1; kif->kf_structsize = roundup(kif->kf_structsize, sizeof(uint64_t)); @@ -3003,6 +3004,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER_ARGS) strlcpy(kif->kf_path, tty_devname(tp), sizeof(kif->kf_path)); } + /* Pack record size down */ kif->kf_structsize = offsetof(struct kinfo_file, kf_path) + strlen(kif->kf_path) + 1; kif->kf_structsize = roundup(kif->kf_structsize, diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index e8e6e00..bb66f04 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -32,6 +32,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_compat.h" #include "opt_ddb.h" #include "opt_kdtrace.h" #include "opt_ktrace.h" @@ -1337,6 +1338,173 @@ sysctl_kern_proc_sv_name(SYSCTL_HANDLER_ARGS) return (sysctl_handle_string(oidp, sv_name, 0, req)); } +#ifdef KINFO_OVMENTRY_SIZE +CTASSERT(sizeof(struct kinfo_ovmentry) == KINFO_OVMENTRY_SIZE); +#endif + +#ifdef COMPAT_FREEBSD7 +static int +sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_ARGS) +{ + vm_map_entry_t entry, tmp_entry; + unsigned int last_timestamp; + char *fullpath, *freepath; + struct kinfo_ovmentry *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_structsize = 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 = (void *)entry->start; + kve->kve_end = (void *)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); + error = SYSCTL_OUT(req, kve, sizeof(*kve)); + 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); +} +#endif /* COMPAT_FREEBSD7 */ + #ifdef KINFO_VMENTRY_SIZE CTASSERT(sizeof(struct kinfo_vmentry) == KINFO_VMENTRY_SIZE); #endif @@ -1383,7 +1551,6 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_ARGS) continue; bzero(kve, sizeof(*kve)); - kve->kve_structsize = sizeof(*kve); kve->kve_private_resident = 0; obj = entry->object.vm_object; @@ -1487,7 +1654,12 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_ARGS) last_timestamp = map->timestamp; vm_map_unlock_read(map); - error = SYSCTL_OUT(req, kve, sizeof(*kve)); + /* 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; @@ -1673,6 +1845,11 @@ static SYSCTL_NODE(_kern_proc, (KERN_PROC_PID | KERN_PROC_INC_THREAD), pid_td, static SYSCTL_NODE(_kern_proc, (KERN_PROC_PROC | KERN_PROC_INC_THREAD), proc_td, CTLFLAG_RD, sysctl_kern_proc, "Return process table, no threads"); +#ifdef COMPAT_FREEBSD7 +static SYSCTL_NODE(_kern_proc, KERN_PROC_OVMMAP, ovmmap, CTLFLAG_RD, + sysctl_kern_proc_ovmmap, "Old Process vm map entries"); +#endif + static SYSCTL_NODE(_kern_proc, KERN_PROC_VMMAP, vmmap, CTLFLAG_RD, sysctl_kern_proc_vmmap, "Process vm map entries"); diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index e4e3040..f1cb04a 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -540,14 +540,16 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry); #define KERN_PROC_RGID 10 /* by real group id */ #define KERN_PROC_GID 11 /* by effective group id */ #define KERN_PROC_PATHNAME 12 /* path to executable */ -#define KERN_PROC_VMMAP 13 /* VM map entries for process */ +#define KERN_PROC_OVMMAP 13 /* Old VM map entries for process */ #define KERN_PROC_OFILEDESC 14 /* Old file descriptors for process */ #define KERN_PROC_KSTACK 15 /* Kernel stacks for process */ #define KERN_PROC_INC_THREAD 0x10 /* * modifier for pid, pgrp, tty, * uid, ruid, gid, rgid and proc + * This effectively uses 16-31 */ -#define KERN_PROC_FILEDESC 32 /* File descriptors for process */ +#define KERN_PROC_VMMAP 32 /* VM map entries for process */ +#define KERN_PROC_FILEDESC 33 /* File descriptors for process */ /* * KERN_IPC identifiers diff --git a/sys/sys/user.h b/sys/sys/user.h index 4f11765..73f7d76 100644 --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -348,6 +348,32 @@ struct kinfo_file { #define KVME_FLAG_COW 0x00000001 #define KVME_FLAG_NEEDS_COPY 0x00000002 +#if defined(__amd64__) +#define KINFO_OVMENTRY_SIZE 1168 +#endif +#if defined(__i386__) +#define KINFO_OVMENTRY_SIZE 1128 +#endif + +struct kinfo_ovmentry { + int kve_structsize; /* Size of kinfo_vmmapentry. */ + int kve_type; /* Type of map entry. */ + void *kve_start; /* Starting address. */ + void *kve_end; /* Finishing address. */ + int kve_flags; /* Flags on map entry. */ + int kve_resident; /* Number of resident pages. */ + int kve_private_resident; /* Number of private pages. */ + int kve_protection; /* Protection bitmask. */ + int kve_ref_count; /* VM obj ref count. */ + int kve_shadow_count; /* VM obj shadow count. */ + char kve_path[PATH_MAX]; /* Path to VM obj, if any. */ + void *_kve_pspare[8]; /* Space for more stuff. */ + off_t kve_offset; /* Mapping offset in object */ + uint64_t kve_fileid; /* inode number if vnode */ + dev_t kve_fsid; /* dev_t of vnode location */ + int _kve_ispare[3]; /* Space for more stuff. */ +}; + #if defined(__amd64__) || defined(__i386__) #define KINFO_VMENTRY_SIZE 1160 #endif |