Index: sys/kern/kern_proc.c =================================================================== --- sys/kern/kern_proc.c +++ sys/kern/kern_proc.c @@ -2536,12 +2536,14 @@ last_timestamp = map->timestamp; vm_map_unlock_read(map); - freepath = NULL; - fullpath = ""; if (lobj != NULL) { kve->kve_type = vm_object_kvme_type(lobj, &vp); if (vp != NULL) vref(vp); + else if (lobj->path_info != NULL) + lobj->path_info(lobj->path_info_data, + kve->kve_path, + sizeof(kve->kve_path)); if (lobj != obj) VM_OBJECT_RUNLOCK(lobj); @@ -2549,6 +2551,8 @@ kve->kve_shadow_count = obj->shadow_count; VM_OBJECT_RUNLOCK(obj); if (vp != NULL) { + freepath = NULL; + fullpath = ""; vn_fullpath(curthread, vp, &fullpath, &freepath); kve->kve_vn_type = vntype_to_kinfo(vp->v_type); @@ -2568,6 +2572,10 @@ kve->kve_status = KF_ATTR_VALID; } vput(vp); + strlcpy(kve->kve_path, fullpath, + sizeof(kve->kve_path)); + if (freepath != NULL) + free(freepath, M_TEMP); } } else { kve->kve_type = KVME_TYPE_NONE; @@ -2575,10 +2583,6 @@ kve->kve_shadow_count = 0; } - strlcpy(kve->kve_path, fullpath, sizeof(kve->kve_path)); - if (freepath != NULL) - free(freepath, M_TEMP); - /* Pack record size down */ if ((flags & KERN_VMMAP_PACK_KINFO) != 0) kve->kve_structsize = Index: sys/kern/kern_umtx.c =================================================================== --- sys/kern/kern_umtx.c +++ sys/kern/kern_umtx.c @@ -3832,7 +3832,7 @@ reg = uma_zalloc(umtx_shm_reg_zone, M_WAITOK | M_ZERO); reg->ushm_refcnt = 1; bcopy(key, ®->ushm_key, sizeof(*key)); - reg->ushm_obj = shm_alloc(td->td_ucred, O_RDWR); + reg->ushm_obj = shm_alloc(NULL, td->td_ucred, O_RDWR); reg->ushm_cred = crhold(cred); error = shm_dotruncate(reg->ushm_obj, PAGE_SIZE); if (error != 0) { Index: sys/kern/sysv_shm.c =================================================================== --- sys/kern/sysv_shm.c +++ sys/kern/sysv_shm.c @@ -685,6 +685,15 @@ return (0); } +static void +shmget_path_info(void *data, char *buffer, size_t size) +{ + key_t key = (key_t) data; + + if (key != IPC_PRIVATE) + snprintf(buffer, size, "%ld", (key_t) data); +} + static int shmget_allocate_segment(struct thread *td, struct shmget_args *uap, int mode) { @@ -752,6 +761,8 @@ return (ENOMEM); } shm_object->pg_color = 0; + shm_object->path_info_data = (void *) uap->key; + shm_object->path_info = shmget_path_info; VM_OBJECT_WLOCK(shm_object); vm_object_clear_flag(shm_object, OBJ_ONEMAPPING); vm_object_set_flag(shm_object, OBJ_COLORED | OBJ_NOSPLIT); Index: sys/kern/uipc_shm.c =================================================================== --- sys/kern/uipc_shm.c +++ sys/kern/uipc_shm.c @@ -545,12 +545,30 @@ return (0); } +static void +shm_path_info(void *data, char *buffer, size_t size) +{ + const char *path = (const char *) data; + const char *pr_path = curthread->td_ucred->cr_prison->pr_path; + size_t pr_pathlen; + + if (path == NULL) { + strlcpy(buffer, "(unlinked)", size); + } else if (strcmp(pr_path, "/") == 0) { + strlcpy(buffer, path, size); + } else { + pr_pathlen = strlen(pr_path); + if (strncmp(path, pr_path, pr_pathlen) == 0) + strlcpy(buffer, path + pr_pathlen, size); + } +} + /* * shmfd object management including creation and reference counting * routines. */ struct shmfd * -shm_alloc(struct ucred *ucred, mode_t mode) +shm_alloc(char *path, struct ucred *ucred, mode_t mode) { struct shmfd *shmfd; @@ -563,6 +581,10 @@ shmfd->shm_size, VM_PROT_DEFAULT, 0, ucred); KASSERT(shmfd->shm_object != NULL, ("shm_create: vm_pager_allocate")); shmfd->shm_object->pg_color = 0; + if (path != NULL) { + shmfd->shm_object->path_info_data = path; + shmfd->shm_object->path_info = shm_path_info; + } VM_OBJECT_WLOCK(shmfd->shm_object); vm_object_clear_flag(shmfd->shm_object, OBJ_ONEMAPPING); vm_object_set_flag(shmfd->shm_object, OBJ_COLORED | OBJ_NOSPLIT); @@ -693,6 +715,9 @@ if (error) return (error); map->sm_shmfd->shm_path = NULL; + VM_OBJECT_WLOCK(map->sm_shmfd->shm_object); + map->sm_shmfd->shm_object->path_info_data = NULL; + VM_OBJECT_WUNLOCK(map->sm_shmfd->shm_object); LIST_REMOVE(map, sm_link); shm_drop(map->sm_shmfd); free(map->sm_path, M_SHMFD); @@ -750,7 +775,7 @@ fdrop(fp, td); return (EINVAL); } - shmfd = shm_alloc(td->td_ucred, cmode); + shmfd = shm_alloc(NULL, td->td_ucred, cmode); } else { path = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK); pr_path = td->td_ucred->cr_prison->pr_path; @@ -786,7 +811,7 @@ path); if (error == 0) { #endif - shmfd = shm_alloc(td->td_ucred, cmode); + shmfd = shm_alloc(path, td->td_ucred, cmode); shm_insert(path, fnv, shmfd); #ifdef MAC } Index: sys/sys/mman.h =================================================================== --- sys/sys/mman.h +++ sys/sys/mman.h @@ -238,7 +238,7 @@ int shm_unmap(struct file *fp, void *mem, size_t size); int shm_access(struct shmfd *shmfd, struct ucred *ucred, int flags); -struct shmfd *shm_alloc(struct ucred *ucred, mode_t mode); +struct shmfd *shm_alloc(char *path, struct ucred *ucred, mode_t mode); struct shmfd *shm_hold(struct shmfd *shmfd); void shm_drop(struct shmfd *shmfd); int shm_dotruncate(struct shmfd *shmfd, off_t length); Index: sys/vm/vm_object.h =================================================================== --- sys/vm/vm_object.h +++ sys/vm/vm_object.h @@ -172,6 +172,8 @@ struct ucred *cred; vm_ooffset_t charge; void *umtx_data; + void *path_info_data; /* callback + data for procstat path */ + void (*path_info)(void *data, char *buffer, size_t size); }; /* Index: sys/vm/vm_object.c =================================================================== --- sys/vm/vm_object.c +++ sys/vm/vm_object.c @@ -287,6 +287,8 @@ LIST_INIT(&object->rvq); #endif umtx_shm_object_init(object); + object->path_info_data = NULL; + object->path_info = NULL; } /*