From owner-svn-src-all@FreeBSD.ORG Sun Apr 1 18:22:49 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A8CE91065675; Sun, 1 Apr 2012 18:22:49 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 928E48FC1C; Sun, 1 Apr 2012 18:22:49 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q31IMnKO060936; Sun, 1 Apr 2012 18:22:49 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q31IMnVN060925; Sun, 1 Apr 2012 18:22:49 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201204011822.q31IMnVN060925@svn.freebsd.org> From: John Baldwin Date: Sun, 1 Apr 2012 18:22:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r233760 - in head: lib/libprocstat sys/kern sys/sys usr.bin/fstat usr.bin/procstat X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 01 Apr 2012 18:22:49 -0000 Author: jhb Date: Sun Apr 1 18:22:48 2012 New Revision: 233760 URL: http://svn.freebsd.org/changeset/base/233760 Log: Export some more useful info about shared memory objects to userland via procstat(1) and fstat(1): - Change shm file descriptors to track the pathname they are associated with and add a shm_path() method to copy the path out to a caller-supplied buffer. - Use the fo_stat() method of shared memory objects and shm_path() to export the path, mode, and size of a shared memory object via struct kinfo_file. - Add a struct shmstat to the libprocstat(3) interface along with a procstat_get_shm_info() to export the mode and size of a shared memory object. - Change procstat to always print out the path for a given object if it is valid. - Teach fstat about shared memory objects and to display their path, mode, and size. MFC after: 2 weeks Modified: head/lib/libprocstat/Symbol.map head/lib/libprocstat/Versions.def head/lib/libprocstat/libprocstat.3 head/lib/libprocstat/libprocstat.c head/lib/libprocstat/libprocstat.h head/sys/kern/kern_descrip.c head/sys/kern/uipc_shm.c head/sys/sys/mman.h head/usr.bin/fstat/fstat.c head/usr.bin/procstat/procstat_files.c Modified: head/lib/libprocstat/Symbol.map ============================================================================== --- head/lib/libprocstat/Symbol.map Sun Apr 1 15:05:15 2012 (r233759) +++ head/lib/libprocstat/Symbol.map Sun Apr 1 18:22:48 2012 (r233760) @@ -14,3 +14,7 @@ FBSD_1.2 { procstat_open_kvm; procstat_open_sysctl; }; + +FBSD_1.3 { + procstat_get_shm_info; +}; Modified: head/lib/libprocstat/Versions.def ============================================================================== --- head/lib/libprocstat/Versions.def Sun Apr 1 15:05:15 2012 (r233759) +++ head/lib/libprocstat/Versions.def Sun Apr 1 18:22:48 2012 (r233760) @@ -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; + Modified: head/lib/libprocstat/libprocstat.3 ============================================================================== --- head/lib/libprocstat/libprocstat.3 Sun Apr 1 15:05:15 2012 (r233759) +++ head/lib/libprocstat/libprocstat.3 Sun Apr 1 18:22:48 2012 (r233760) @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 12, 2011 +.Dd April 1, 2012 .Dt LIBPROCSTAT 3 .Os .Sh NAME @@ -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 @@ function call. 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 @@ argument indicates an actual error messa .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 , Modified: head/lib/libprocstat/libprocstat.c ============================================================================== --- head/lib/libprocstat/libprocstat.c Sun Apr 1 15:05:15 2012 (r233759) +++ head/lib/libprocstat/libprocstat.c Sun Apr 1 18:22:48 2012 (r233760) @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #define _WANT_FILE #include #include +#include #define _KERNEL #include #include @@ -114,6 +115,10 @@ static int procstat_get_pts_info_sysctl( 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 @@ procstat_getfiles_kvm(struct procstat *p 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 @@ procstat_get_pts_info_sysctl(struct file } 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) { Modified: head/lib/libprocstat/libprocstat.h ============================================================================== --- head/lib/libprocstat/libprocstat.h Sun Apr 1 15:05:15 2012 (r233759) +++ head/lib/libprocstat/libprocstat.h Sun Apr 1 18:22:48 2012 (r233760) @@ -123,6 +123,10 @@ struct pipestat { 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 @@ int procstat_get_pipe_info(struct procst 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, Modified: head/sys/kern/kern_descrip.c ============================================================================== --- head/sys/kern/kern_descrip.c Sun Apr 1 15:05:15 2012 (r233759) +++ head/sys/kern/kern_descrip.c Sun Apr 1 18:22:48 2012 (r233760) @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -126,6 +127,7 @@ static int fill_pts_info(struct tty *tp, 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 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE 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 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE vp = NULL; so = NULL; tp = NULL; + shmfd = NULL; kif->kf_fd = i; #ifdef CAPABILITIES @@ -3046,6 +3050,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE case DTYPE_SHM: kif->kf_type = KF_TYPE_SHM; + shmfd = fp->f_data; break; case DTYPE_SEM: @@ -3159,6 +3164,8 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE 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 @@ export_fd_for_sysctl(void *data, int typ 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 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER case DTYPE_SHM: type = KF_TYPE_SHM; + data = fp; break; case DTYPE_SEM: @@ -3621,6 +3632,23 @@ fill_procdesc_info(struct procdesc *pdp, 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"); Modified: head/sys/kern/uipc_shm.c ============================================================================== --- head/sys/kern/uipc_shm.c Sun Apr 1 15:05:15 2012 (r233759) +++ head/sys/kern/uipc_shm.c Sun Apr 1 18:22:48 2012 (r233760) @@ -468,6 +468,7 @@ shm_insert(char *path, Fnv32_t fnv, stru 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 @@ shm_remove(char *path, Fnv32_t fnv, stru FREAD | FWRITE); if (error) return (error); + map->sm_shmfd->shm_path = NULL; LIST_REMOVE(map, sm_link); shm_drop(map->sm_shmfd); free(map->sm_path, M_SHMFD); @@ -844,3 +846,15 @@ shm_unmap(struct file *fp, void *mem, si VM_OBJECT_UNLOCK(obj); return (0); } + +void +shm_path(struct shmfd *shmfd, char *path, size_t size) +{ + + if (shmfd->shm_path == NULL) + return; + sx_slock(&shm_dict_lock); + if (shmfd->shm_path != NULL) + strlcpy(path, shmfd->shm_path, size); + sx_sunlock(&shm_dict_lock); +} Modified: head/sys/sys/mman.h ============================================================================== --- head/sys/sys/mman.h Sun Apr 1 15:05:15 2012 (r233759) +++ head/sys/sys/mman.h Sun Apr 1 18:22:48 2012 (r233760) @@ -178,7 +178,7 @@ typedef __size_t size_t; #define _SIZE_T_DECLARED #endif -#ifdef _KERNEL +#if defined(_KERNEL) || defined(_WANT_FILE) #include struct file; @@ -202,12 +202,16 @@ struct shmfd { 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 */ Modified: head/usr.bin/fstat/fstat.c ============================================================================== --- head/usr.bin/fstat/fstat.c Sun Apr 1 15:05:15 2012 (r233759) +++ head/usr.bin/fstat/fstat.c Sun Apr 1 18:22:48 2012 (r233760) @@ -84,6 +84,8 @@ static void print_pipe_info(struct procs 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 @@ print_file_info(struct procstat *procsta 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 @@ print_pts_info(struct procstat *procstat } 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 != NULL ? 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; Modified: head/usr.bin/procstat/procstat_files.c ============================================================================== --- head/usr.bin/procstat/procstat_files.c Sun Apr 1 15:05:15 2012 (r233759) +++ head/usr.bin/procstat/procstat_files.c Sun Apr 1 18:22:48 2012 (r233760) @@ -440,13 +440,6 @@ procstat_files(struct procstat *procstat printf(" "); } switch (fst->fs_type) { - case PS_FST_TYPE_VNODE: - case PS_FST_TYPE_FIFO: - case PS_FST_TYPE_PTS: - printf("%-3s ", "-"); - printf("%-18s", fst->fs_path != NULL ? fst->fs_path : "-"); - break; - case PS_FST_TYPE_SOCKET: error = procstat_get_socket_info(procstat, fst, &sock, NULL); if (error != 0) @@ -477,7 +470,8 @@ procstat_files(struct procstat *procstat break; default: - printf("%-18s", "-"); + printf("%-3s ", "-"); + printf("%-18s", fst->fs_path != NULL ? fst->fs_path : "-"); } printf("\n");