Author: jhb
Date: Wed Jun  6 21:57:03 2012
New Revision: 236699
URL: http://svn.freebsd.org/changeset/base/236699

Log:
  MFC 233760:
  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 shm_path() to export the path of a shared memory object via
    struct kinfo_file.
  - 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.

Modified:
  stable/8/sys/kern/kern_descrip.c
  stable/8/sys/kern/uipc_shm.c
  stable/8/sys/sys/mman.h
  stable/8/usr.bin/fstat/fstat.c
  stable/8/usr.bin/procstat/procstat_files.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/boot/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)
  stable/8/usr.bin/fstat/   (props changed)
  stable/8/usr.bin/procstat/   (props changed)

Modified: stable/8/sys/kern/kern_descrip.c
==============================================================================
--- stable/8/sys/kern/kern_descrip.c    Wed Jun  6 21:49:31 2012        
(r236698)
+++ stable/8/sys/kern/kern_descrip.c    Wed Jun  6 21:57:03 2012        
(r236699)
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/limits.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
+#include <sys/mman.h>
 #include <sys/mount.h>
 #include <sys/mqueue.h>
 #include <sys/mutex.h>
@@ -2742,6 +2743,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;
@@ -2779,6 +2781,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE
                vp = NULL;
                so = NULL;
                tp = NULL;
+               shmfd = NULL;
                kif->kf_fd = i;
                switch (fp->f_type) {
                case DTYPE_VNODE:
@@ -2814,6 +2817,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLE
 
                case DTYPE_SHM:
                        kif->kf_type = KF_TYPE_SHM;
+                       shmfd = fp->f_data;
                        break;
 
                case DTYPE_SEM:
@@ -2921,6 +2925,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;
@@ -2995,6 +3001,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
        struct kinfo_file *kif;
        struct filedesc *fdp;
        int error, i, *name;
+       struct shmfd *shmfd;
        struct socket *so;
        struct vnode *vp;
        struct file *fp;
@@ -3032,6 +3039,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
                vp = NULL;
                so = NULL;
                tp = NULL;
+               shmfd = NULL;
                kif->kf_fd = i;
                switch (fp->f_type) {
                case DTYPE_VNODE:
@@ -3067,6 +3075,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
 
                case DTYPE_SHM:
                        kif->kf_type = KF_TYPE_SHM;
+                       shmfd = fp->f_data;
                        break;
 
                case DTYPE_SEM:
@@ -3174,6 +3183,8 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER
                        strlcpy(kif->kf_path, tty_devname(tp),
                            sizeof(kif->kf_path));
                }
+               if (shmfd != NULL)
+                       shm_path(shmfd, kif->kf_path, sizeof(kif->kf_path));
                /* Pack record size down */
                kif->kf_structsize = offsetof(struct kinfo_file, kf_path) +
                    strlen(kif->kf_path) + 1;

Modified: stable/8/sys/kern/uipc_shm.c
==============================================================================
--- stable/8/sys/kern/uipc_shm.c        Wed Jun  6 21:49:31 2012        
(r236698)
+++ stable/8/sys/kern/uipc_shm.c        Wed Jun  6 21:57:03 2012        
(r236699)
@@ -453,6 +453,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);
 }
 
@@ -475,6 +476,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);
@@ -754,3 +756,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: stable/8/sys/sys/mman.h
==============================================================================
--- stable/8/sys/sys/mman.h     Wed Jun  6 21:49:31 2012        (r236698)
+++ stable/8/sys/sys/mman.h     Wed Jun  6 21:57:03 2012        (r236699)
@@ -178,7 +178,7 @@ typedef     __size_t        size_t;
 #define        _SIZE_T_DECLARED
 #endif
 
-#ifdef _KERNEL
+#if defined(_KERNEL) || defined(_WANT_FILE)
 #include <vm/vm.h>
 
 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: stable/8/usr.bin/fstat/fstat.c
==============================================================================
--- stable/8/usr.bin/fstat/fstat.c      Wed Jun  6 21:49:31 2012        
(r236698)
+++ stable/8/usr.bin/fstat/fstat.c      Wed Jun  6 21:57:03 2012        
(r236699)
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
 #define        _WANT_FILE
 #include <sys/file.h>
 #include <sys/conf.h>
+#include <sys/mman.h>
 #define        _KERNEL
 #include <sys/pipe.h>
 #include <sys/mount.h>
@@ -155,6 +156,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 shmtrans(struct shmfd *shmp, int i, int flag);
 void getinetproto(int number);
 int  getfname(const char *filename);
 void usage(void);
@@ -418,6 +420,12 @@ dofiles(struct kinfo_proc *kp)
                                ptstrans(file.f_data, i, file.f_flag);
                }
 #endif
+#ifdef DTYPE_SHM
+               else if (file.f_type == DTYPE_SHM) {
+                       if (checkfile == 0)
+                               shmtrans(file.f_data, i, file.f_flag);
+               }
+#endif
                else {
                        dprintf(stderr,
                            "unknown file type %d for file %d of pid %d\n",
@@ -939,6 +947,55 @@ bad:
        printf("* error\n");
 }
 
+void
+shmtrans(struct shmfd *shmp, int i, int flag)
+{
+       struct shmfd shm;
+       char name[MAXPATHLEN];
+       char mode[15];
+       char rw[3];
+       unsigned j;
+
+       PREFIX(i);
+
+       if (!KVM_READ(shmp, &shm, sizeof(struct shmfd))) {
+               dprintf(stderr, "can't read shm at %p\n", shmp);
+               goto bad;
+       }
+
+       if (shm.shm_path != NULL) {
+               for (j = 0; j < sizeof(name) - 1; j++) {
+                       if (!KVM_READ(shm.shm_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");
+
+       shm.shm_mode |= S_IFREG;
+       if (nflg) {
+               printf("             ");
+               (void)snprintf(mode, sizeof(mode), "%o", shm.shm_mode);
+       } else {
+               printf(" %-15s", name[0] != '\0' ? name : "-");
+               strmode(shm.shm_mode, mode);
+       }
+       printf(" %10s %6ju", mode, shm.shm_size);
+       printf(" %2s\n", rw);
+
+       return;
+bad:
+       printf("* error\n");
+}
+
 /*
  * Read the cdev structure in the kernel in order to work out the
  * associated dev_t

Modified: stable/8/usr.bin/procstat/procstat_files.c
==============================================================================
--- stable/8/usr.bin/procstat/procstat_files.c  Wed Jun  6 21:49:31 2012        
(r236698)
+++ stable/8/usr.bin/procstat/procstat_files.c  Wed Jun  6 21:57:03 2012        
(r236699)
@@ -277,13 +277,6 @@ procstat_files(pid_t pid, struct kinfo_p
                        printf("%7c ", '-');
 
                switch (kif->kf_type) {
-               case KF_TYPE_VNODE:
-               case KF_TYPE_FIFO:
-               case KF_TYPE_PTS:
-                       printf("%-3s ", "-");
-                       printf("%-18s", kif->kf_path);
-                       break;
-
                case KF_TYPE_SOCKET:
                        printf("%-3s ",
                            protocol_to_string(kif->kf_sock_domain,
@@ -312,7 +305,8 @@ procstat_files(pid_t pid, struct kinfo_p
 
                default:
                        printf("%-3s ", "-");
-                       printf("%-18s", "-");
+                       printf("%-18s", kif->kf_path[0] != '\0' ?
+                           kif->kf_path : "-");
                }
 
                printf("\n");
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to