Index: usr.bin/procstat/procstat_files.c =================================================================== --- usr.bin/procstat/procstat_files.c (revision 233435) +++ usr.bin/procstat/procstat_files.c (working copy) @@ -443,6 +443,7 @@ case PS_FST_TYPE_VNODE: case PS_FST_TYPE_FIFO: case PS_FST_TYPE_PTS: + case PS_FST_TYPE_SHM: printf("%-3s ", "-"); printf("%-18s", fst->fs_path != NULL ? fst->fs_path : "-"); break; @@ -477,6 +478,7 @@ break; default: + printf("%-3s ", "-"); printf("%-18s", "-"); } Index: usr.bin/fstat/fstat.c =================================================================== --- usr.bin/fstat/fstat.c (revision 233435) +++ usr.bin/fstat/fstat.c (working copy) @@ -84,6 +84,8 @@ struct filestat *fst); static void print_pts_info(struct procstat *procstat, struct filestat *fst); +static void print_shm_info(struct procstat *procstat, + struct filestat *fst); static void print_socket_info(struct procstat *procstat, struct filestat *fst); static void print_vnode_info(struct procstat *procstat, @@ -289,6 +291,9 @@ case PS_FST_TYPE_PTS: print_pts_info(procstat, fst); break; + case PS_FST_TYPE_SHM: + print_shm_info(procstat, fst); + break; default: if (vflg) fprintf(stderr, @@ -419,6 +424,30 @@ } static void +print_shm_info(struct procstat *procstat, struct filestat *fst) +{ + struct shmstat shm; + char errbuf[_POSIX2_LINE_MAX]; + char mode[15]; + int error; + + error = procstat_get_shm_info(procstat, fst, &shm, errbuf); + if (error != 0) { + printf("* error"); + return; + } + if (nflg) { + printf(" "); + (void)snprintf(mode, sizeof(mode), "%o", shm.mode); + } else { + printf(" %-15s", fst->fs_path); + strmode(shm.mode, mode); + } + printf(" %10s %6ju", mode, shm.size); + print_access_flags(fst->fs_fflags); +} + +static void print_vnode_info(struct procstat *procstat, struct filestat *fst) { struct vnstat vn; Index: lib/libprocstat/Symbol.map =================================================================== --- lib/libprocstat/Symbol.map (revision 233435) +++ lib/libprocstat/Symbol.map (working copy) @@ -14,3 +14,7 @@ procstat_open_kvm; procstat_open_sysctl; }; + +FBSD_1.3 { + procstat_get_shm_info; +}; Index: lib/libprocstat/libprocstat.3 =================================================================== --- lib/libprocstat/libprocstat.3 (revision 233435) +++ lib/libprocstat/libprocstat.3 (working copy) @@ -37,6 +37,7 @@ .Nm procstat_freeprocs , .Nm procstat_get_pipe_info , .Nm procstat_get_pts_info , +.Nm procstat_get_shm_info , .Nm procstat_get_socket_info , .Nm procstat_get_vnode_info .Nd library interface for file and process information retrieval @@ -70,6 +71,13 @@ .Fa "char *errbuf" .Fc .Ft int +.Fo procstat_get_shm_info +.Fa "struct procstat *procstat" +.Fa "struct filestat *fst" +.Fa "struct shmstat *shm" +.Fa "char *errbuf" +.Fc +.Ft int .Fo procstat_get_socket_info .Fa "struct procstat *procstat" .Fa "struct filestat *fst" @@ -191,10 +199,12 @@ The .Fn procstat_get_pipe_info , .Fn procstat_get_pts_info , +.Fn procstat_get_shm_info , .Fn procstat_get_socket_info and .Fn procstat_get_vnode_info functions are used to retrive information about pipes, pseudo-terminals, +shared memory objects, sockets, and vnodes, respectively. Each of them have a similar interface API. The @@ -231,11 +241,14 @@ .Nm procstat_get_pipe_info .It Li PS_FST_TYPE_PTS .Nm procstat_get_pts_info +.It Li PS_FST_TYPE_SHM +.Nm procstat_get_shm_info .El .Sh SEE ALSO .Xr fstat 1 , .Xr fuser 1 , .Xr pipe 2 , +.Xr shm_open 2 , .Xr socket 2 , .Xr kvm 3 , .Xr queue 3 , Index: lib/libprocstat/Versions.def =================================================================== --- lib/libprocstat/Versions.def (revision 233435) +++ lib/libprocstat/Versions.def (working copy) @@ -3,3 +3,8 @@ # This version was first added to 9.0-current. FBSD_1.2 { }; + +# This version was first added to 10.0-current. +FBSD_1.3 { +} FBSD_1.2; + Index: lib/libprocstat/libprocstat.c =================================================================== --- lib/libprocstat/libprocstat.c (revision 233435) +++ lib/libprocstat/libprocstat.c (working copy) @@ -54,6 +54,7 @@ #define _WANT_FILE #include #include +#include #define _KERNEL #include #include @@ -114,6 +115,10 @@ struct ptsstat *pts, char *errbuf); static int procstat_get_pts_info_kvm(kvm_t *kd, struct filestat *fst, struct ptsstat *pts, char *errbuf); +static int procstat_get_shm_info_sysctl(struct filestat *fst, + struct shmstat *shm, char *errbuf); +static int procstat_get_shm_info_kvm(kvm_t *kd, struct filestat *fst, + struct shmstat *shm, char *errbuf); static int procstat_get_socket_info_sysctl(struct filestat *fst, struct sockstat *sock, char *errbuf); static int procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst, @@ -469,6 +474,10 @@ data = file.f_data; break; #endif + case DTYPE_SHM: + type = PS_FST_TYPE_SHM; + data = file.f_data; + break; default: continue; } @@ -849,6 +858,69 @@ } int +procstat_get_shm_info(struct procstat *procstat, struct filestat *fst, + struct shmstat *shm, char *errbuf) +{ + + assert(shm); + if (procstat->type == PROCSTAT_KVM) { + return (procstat_get_shm_info_kvm(procstat->kd, fst, shm, + errbuf)); + } else if (procstat->type == PROCSTAT_SYSCTL) { + return (procstat_get_shm_info_sysctl(fst, shm, errbuf)); + } else { + warnx("unknown access method: %d", procstat->type); + snprintf(errbuf, _POSIX2_LINE_MAX, "error"); + return (1); + } +} + +static int +procstat_get_shm_info_kvm(kvm_t *kd, struct filestat *fst, + struct shmstat *shm, char *errbuf) +{ + struct shmfd shmfd; + void *shmfdp; + + assert(kd); + assert(shm); + assert(fst); + bzero(shm, sizeof(*shm)); + shmfdp = fst->fs_typedep; + if (shmfdp == NULL) + goto fail; + if (!kvm_read_all(kd, (unsigned long)shmfdp, &shmfd, + sizeof(struct shmfd))) { + warnx("can't read shmfd at %p", (void *)shmfdp); + goto fail; + } + shm->mode = S_IFREG | shmfd.shm_mode; + shm->size = shmfd.shm_size; + return (0); + +fail: + snprintf(errbuf, _POSIX2_LINE_MAX, "error"); + return (1); +} + +static int +procstat_get_shm_info_sysctl(struct filestat *fst, struct shmstat *shm, + char *errbuf __unused) +{ + struct kinfo_file *kif; + + assert(shm); + assert(fst); + bzero(shm, sizeof(*shm)); + kif = fst->fs_typedep; + if (kif == NULL) + return (0); + shm->size = kif->kf_un.kf_file.kf_file_size; + shm->mode = kif->kf_un.kf_file.kf_file_mode; + return (0); +} + +int procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst, struct vnstat *vn, char *errbuf) { Index: lib/libprocstat/libprocstat.h =================================================================== --- lib/libprocstat/libprocstat.h (revision 233435) +++ lib/libprocstat/libprocstat.h (working copy) @@ -123,6 +123,10 @@ uint64_t addr; uint64_t peer; }; +struct shmstat { + uint64_t size; + uint16_t mode; +}; struct sockstat { uint64_t inp_ppcb; uint64_t so_addr; @@ -152,6 +156,8 @@ struct pipestat *pipe, char *errbuf); int procstat_get_pts_info(struct procstat *procstat, struct filestat *fst, struct ptsstat *pts, char *errbuf); +int procstat_get_shm_info(struct procstat *procstat, struct filestat *fst, + struct shmstat *shm, char *errbuf); int procstat_get_socket_info(struct procstat *procstat, struct filestat *fst, struct sockstat *sock, char *errbuf); int procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst, Index: sys/kern/uipc_shm.c =================================================================== --- sys/kern/uipc_shm.c (revision 233435) +++ sys/kern/uipc_shm.c (working copy) @@ -468,6 +468,7 @@ map->sm_path = path; map->sm_fnv = fnv; map->sm_shmfd = shm_hold(shmfd); + shmfd->shm_path = path; LIST_INSERT_HEAD(SHM_HASH(fnv), map, sm_link); } @@ -490,6 +491,7 @@ FREAD | FWRITE); if (error) return (error); + map->sm_shmfd->shm_path = "-"; LIST_REMOVE(map, sm_link); shm_drop(map->sm_shmfd); free(map->sm_path, M_SHMFD); @@ -544,6 +546,7 @@ return (EINVAL); } shmfd = shm_alloc(td->td_ucred, cmode); + shmfd->shm_path = "SHM_ANON"; } else { path = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK); error = copyinstr(uap->path, path, MAXPATHLEN, NULL); @@ -844,3 +847,12 @@ VM_OBJECT_UNLOCK(obj); return (0); } + +void +shm_path(struct shmfd *shmfd, char *path, size_t size) +{ + + sx_slock(&shm_dict_lock); + strlcpy(path, shmfd->shm_path, size); + sx_sunlock(&shm_dict_lock); +} Index: sys/kern/kern_descrip.c =================================================================== --- sys/kern/kern_descrip.c (revision 233435) +++ sys/kern/kern_descrip.c (working copy) @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -126,6 +127,7 @@ static int fill_pipe_info(struct pipe *pi, struct kinfo_file *kif); static int fill_procdesc_info(struct procdesc *pdp, struct kinfo_file *kif); +static int fill_shm_info(struct file *fp, struct kinfo_file *kif); /* * A process is initially started out with NDFILE descriptors stored within @@ -2958,6 +2960,7 @@ struct kinfo_ofile *kif; struct filedesc *fdp; int error, i, *name; + struct shmfd *shmfd; struct socket *so; struct vnode *vp; struct file *fp; @@ -2995,6 +2998,7 @@ vp = NULL; so = NULL; tp = NULL; + shmfd = NULL; kif->kf_fd = i; #ifdef CAPABILITIES @@ -3046,6 +3050,7 @@ case DTYPE_SHM: kif->kf_type = KF_TYPE_SHM; + shmfd = fp->f_data; break; case DTYPE_SEM: @@ -3159,6 +3164,8 @@ strlcpy(kif->kf_path, tty_devname(tp), sizeof(kif->kf_path)); } + if (shmfd != NULL) + shm_path(shmfd, kif->kf_path, sizeof(kif->kf_path)); error = SYSCTL_OUT(req, kif, sizeof(*kif)); if (error) break; @@ -3229,6 +3236,9 @@ case KF_TYPE_PROCDESC: error = fill_procdesc_info((struct procdesc *)data, kif); break; + case KF_TYPE_SHM: + error = fill_shm_info((struct file *)data, kif); + break; default: error = 0; } @@ -3398,6 +3408,7 @@ case DTYPE_SHM: type = KF_TYPE_SHM; + data = fp; break; case DTYPE_SEM: @@ -3621,6 +3632,23 @@ return (0); } +static int +fill_shm_info(struct file *fp, struct kinfo_file *kif) +{ + struct thread *td; + struct stat sb; + + td = curthread; + if (fp->f_data == NULL) + return (1); + if (fo_stat(fp, &sb, td->td_ucred, td) != 0) + return (1); + shm_path(fp->f_data, kif->kf_path, sizeof(kif->kf_path)); + kif->kf_un.kf_file.kf_file_mode = sb.st_mode; + kif->kf_un.kf_file.kf_file_size = sb.st_size; + return (0); +} + static SYSCTL_NODE(_kern_proc, KERN_PROC_FILEDESC, filedesc, CTLFLAG_RD, sysctl_kern_proc_filedesc, "Process filedesc entries"); Index: sys/sys/mman.h =================================================================== --- sys/sys/mman.h (revision 233435) +++ sys/sys/mman.h (working copy) @@ -178,7 +178,7 @@ #define _SIZE_T_DECLARED #endif -#ifdef _KERNEL +#if defined(_KERNEL) || defined(_WANT_FILE) #include struct file; @@ -202,12 +202,16 @@ struct timespec shm_birthtime; struct label *shm_label; /* MAC label */ + const char *shm_path; }; +#endif +#ifdef _KERNEL int shm_mmap(struct shmfd *shmfd, vm_size_t objsize, vm_ooffset_t foff, vm_object_t *obj); int shm_map(struct file *fp, size_t size, off_t offset, void **memp); int shm_unmap(struct file *fp, void *mem, size_t size); +void shm_path(struct shmfd *shmfd, char *path, size_t size); #else /* !_KERNEL */