From owner-svn-src-all@FreeBSD.ORG Mon Jun 24 17:09:30 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 246537E3; Mon, 24 Jun 2013 17:09:30 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 15A7B12BD; Mon, 24 Jun 2013 17:09:30 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r5OH9TV8065953; Mon, 24 Jun 2013 17:09:29 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r5OH9Tb5065947; Mon, 24 Jun 2013 17:09:29 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201306241709.r5OH9Tb5065947@svn.freebsd.org> From: John Baldwin Date: Mon, 24 Jun 2013 17:09:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r252164 - in stable/8: sys/kern sys/sys usr.bin/fstat X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 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: Mon, 24 Jun 2013 17:09:30 -0000 Author: jhb Date: Mon Jun 24 17:09:28 2013 New Revision: 252164 URL: http://svnweb.freebsd.org/changeset/base/252164 Log: MFC 250223: Similar to 233760 and 236717, export some more useful info about the kernel-based POSIX semaphore descriptors to userland via procstat(1) and fstat(1): - Change sem file descriptors to track the pathname they are associated with and add a ksem_info() method to copy the path out to a caller-supplied buffer. - Use ksem_info() to export the path of a semaphore via struct kinfo_file. - Teach fstat about semaphores and to display their path, mode, and value. Modified: stable/8/sys/kern/kern_descrip.c stable/8/sys/kern/uipc_sem.c stable/8/sys/sys/ksem.h stable/8/usr.bin/fstat/fstat.1 stable/8/usr.bin/fstat/fstat.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/kern/ (props changed) stable/8/sys/sys/ (props changed) stable/8/usr.bin/fstat/ (props changed) Modified: stable/8/sys/kern/kern_descrip.c ============================================================================== --- stable/8/sys/kern/kern_descrip.c Mon Jun 24 16:04:59 2013 (r252163) +++ stable/8/sys/kern/kern_descrip.c Mon Jun 24 17:09:28 2013 (r252164) @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -96,6 +97,7 @@ MALLOC_DECLARE(M_FADVISE); static uma_zone_t file_zone; +void (*ksem_info)(struct ksem *ks, char *path, size_t size, uint32_t *value); /* Flags for do_dup() */ #define DUP_FIXED 0x1 /* Force fixed allocation */ @@ -2764,6 +2766,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE struct shmfd *shmfd; struct socket *so; struct vnode *vp; + struct ksem *ks; struct file *fp; struct proc *p; struct tty *tp; @@ -2796,6 +2799,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE continue; bzero(kif, sizeof(*kif)); kif->kf_structsize = sizeof(*kif); + ks = NULL; vp = NULL; so = NULL; tp = NULL; @@ -2840,6 +2844,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE case DTYPE_SEM: kif->kf_type = KF_TYPE_SEM; + ks = fp->f_data; break; case DTYPE_PTS: @@ -2945,6 +2950,8 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE } if (shmfd != NULL) shm_path(shmfd, kif->kf_path, sizeof(kif->kf_path)); + if (ks != NULL && ksem_info != NULL) + ksem_info(ks, kif->kf_path, sizeof(kif->kf_path), NULL); error = SYSCTL_OUT(req, kif, sizeof(*kif)); if (error) break; @@ -3022,6 +3029,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER struct shmfd *shmfd; struct socket *so; struct vnode *vp; + struct ksem *ks; struct file *fp; struct proc *p; struct tty *tp; @@ -3054,6 +3062,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER if ((fp = fdp->fd_ofiles[i]) == NULL) continue; bzero(kif, sizeof(*kif)); + ks = NULL; vp = NULL; so = NULL; tp = NULL; @@ -3098,6 +3107,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER case DTYPE_SEM: kif->kf_type = KF_TYPE_SEM; + ks = fp->f_data; break; case DTYPE_PTS: @@ -3203,6 +3213,8 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER } if (shmfd != NULL) shm_path(shmfd, kif->kf_path, sizeof(kif->kf_path)); + if (ks != NULL && ksem_info != NULL) + ksem_info(ks, kif->kf_path, sizeof(kif->kf_path), NULL); /* Pack record size down */ kif->kf_structsize = offsetof(struct kinfo_file, kf_path) + strlen(kif->kf_path) + 1; Modified: stable/8/sys/kern/uipc_sem.c ============================================================================== --- stable/8/sys/kern/uipc_sem.c Mon Jun 24 16:04:59 2013 (r252163) +++ stable/8/sys/kern/uipc_sem.c Mon Jun 24 17:09:28 2013 (r252164) @@ -344,6 +344,7 @@ ksem_insert(char *path, Fnv32_t fnv, str map->km_path = path; map->km_fnv = fnv; map->km_ksem = ksem_hold(ks); + ks->ks_path = path; LIST_INSERT_HEAD(KSEM_HASH(fnv), map, km_link); } @@ -365,6 +366,7 @@ ksem_remove(char *path, Fnv32_t fnv, str error = ksem_access(map->km_ksem, ucred); if (error) return (error); + map->km_ksem->ks_path = NULL; LIST_REMOVE(map, km_link); ksem_drop(map->km_ksem); free(map->km_path, M_KSEM); @@ -376,6 +378,20 @@ ksem_remove(char *path, Fnv32_t fnv, str return (ENOENT); } +static void +ksem_info_impl(struct ksem *ks, char *path, size_t size, uint32_t *value) +{ + + if (ks->ks_path == NULL) + return; + sx_slock(&ksem_dict_lock); + if (ks->ks_path != NULL) + strlcpy(path, ks->ks_path, size); + if (value != NULL) + *value = ks->ks_value; + sx_sunlock(&ksem_dict_lock); +} + static int ksem_create_copyout_semid(struct thread *td, semid_t *semidp, int fd, int compat32) @@ -953,6 +969,7 @@ ksem_module_init(void) p31b_setcfg(CTL_P1003_1B_SEMAPHORES, 200112L); p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX); p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX); + ksem_info = ksem_info_impl; error = syscall_helper_register(ksem_syscalls); if (error) @@ -974,6 +991,7 @@ ksem_module_destroy(void) #endif syscall_helper_unregister(ksem_syscalls); + ksem_info = NULL; p31b_setcfg(CTL_P1003_1B_SEMAPHORES, 0); hashdestroy(ksem_dictionary, M_KSEM, ksem_hash); sx_destroy(&ksem_dict_lock); Modified: stable/8/sys/sys/ksem.h ============================================================================== --- stable/8/sys/sys/ksem.h Mon Jun 24 16:04:59 2013 (r252163) +++ stable/8/sys/sys/ksem.h Mon Jun 24 17:09:28 2013 (r252164) @@ -29,7 +29,7 @@ #ifndef _POSIX4_KSEM_H_ #define _POSIX4_KSEM_H_ -#ifndef _KERNEL +#if !defined(_KERNEL) && !defined(_WANT_FILE) #error "no user-servicable parts inside" #endif @@ -57,9 +57,15 @@ struct ksem { struct timespec ks_birthtime; struct label *ks_label; /* MAC label */ + const char *ks_path; }; #define KS_ANONYMOUS 0x0001 /* Anonymous (unnamed) semaphore. */ #define KS_DEAD 0x0002 /* No new waiters allowed. */ +#ifdef _KERNEL +extern void (*ksem_info)(struct ksem *ks, char *path, size_t size, + uint32_t *value); +#endif + #endif /* !_POSIX4_KSEM_H_ */ Modified: stable/8/usr.bin/fstat/fstat.1 ============================================================================== --- stable/8/usr.bin/fstat/fstat.1 Mon Jun 24 16:04:59 2013 (r252163) +++ stable/8/usr.bin/fstat/fstat.1 Mon Jun 24 17:09:28 2013 (r252164) @@ -159,6 +159,8 @@ using a symbolic format (see otherwise, the mode is printed as an octal number. .It Li SZ\&|DV +If the file is a semaphore, +prints the current value of the semaphore. If the file is not a character or block special, prints the size of the file in bytes. Otherwise, if the Modified: stable/8/usr.bin/fstat/fstat.c ============================================================================== --- stable/8/usr.bin/fstat/fstat.c Mon Jun 24 16:04:59 2013 (r252163) +++ stable/8/usr.bin/fstat/fstat.c Mon Jun 24 17:09:28 2013 (r252164) @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #define _WANT_FILE #include #include +#include #include #define _KERNEL #include @@ -156,6 +157,7 @@ char *getmnton(struct mount *m); void pipetrans(struct pipe *pi, int i, int flag); void socktrans(struct socket *sock, int i); void ptstrans(struct tty *tp, int i, int flag); +void semtrans(struct ksem *ksemp, int i, int flag); void shmtrans(struct shmfd *shmp, int i, int flag); void getinetproto(int number); int getfname(const char *filename); @@ -426,6 +428,12 @@ dofiles(struct kinfo_proc *kp) shmtrans(file.f_data, i, file.f_flag); } #endif +#ifdef DTYPE_SEM + else if (file.f_type == DTYPE_SEM) { + if (checkfile == 0) + semtrans(file.f_data, i, file.f_flag); + } +#endif else { dprintf(stderr, "unknown file type %d for file %d of pid %d\n", @@ -948,6 +956,55 @@ bad: } void +semtrans(struct ksem *ksemp, int i, int flag) +{ + struct ksem ks; + char name[MAXPATHLEN]; + char mode[15]; + char rw[3]; + unsigned j; + + PREFIX(i); + + if (!KVM_READ(ksemp, &ks, sizeof(struct ksem))) { + dprintf(stderr, "can't read sem at %p\n", ksemp); + goto bad; + } + + if (ks.ks_path != NULL) { + for (j = 0; j < sizeof(name) - 1; j++) { + if (!KVM_READ(ks.ks_path + j, name + j, 1)) + break; + if (name[j] == '\0') + break; + } + name[j] = '\0'; + } else + name[0] = '\0'; + + rw[0] = '\0'; + if (flag & FREAD) + strcat(rw, "r"); + if (flag & FWRITE) + strcat(rw, "w"); + + ks.ks_mode |= S_IFREG; + if (nflg) { + printf(" "); + (void)snprintf(mode, sizeof(mode), "%o", ks.ks_mode); + } else { + printf(" %-15s", name[0] != '\0' ? name : "-"); + strmode(ks.ks_mode, mode); + } + printf(" %10s %6u", mode, ks.ks_value); + printf(" %2s\n", rw); + + return; +bad: + printf("* error\n"); +} + +void shmtrans(struct shmfd *shmp, int i, int flag) { struct shmfd shm;