Print this page
XXXX adding PID information to netstat output

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/sockfs/socksubr.c
          +++ new/usr/src/uts/common/fs/sockfs/socksubr.c
↓ open down ↓ 105 lines elided ↑ open up ↑
 106  106  static int sockfs_update(kstat_t *, int);
 107  107  static int sockfs_snapshot(kstat_t *, void *, int);
 108  108  extern smod_info_t *sotpi_smod_create(void);
 109  109  
 110  110  extern void sendfile_init();
 111  111  
 112  112  extern void nl7c_init(void);
 113  113  
 114  114  extern int modrootloaded;
 115  115  
 116      -#define ADRSTRLEN (2 * sizeof (void *) + 1)
 117      -/*
 118      - * kernel structure for passing the sockinfo data back up to the user.
 119      - * the strings array allows us to convert AF_UNIX addresses into strings
 120      - * with a common method regardless of which n-bit kernel we're running.
 121      - */
 122      -struct k_sockinfo {
 123      -        struct sockinfo ks_si;
 124      -        char            ks_straddr[3][ADRSTRLEN];
 125      -};
 126      -
 127  116  /*
 128  117   * Translate from a device pathname (e.g. "/dev/tcp") to a vnode.
 129  118   * Returns with the vnode held.
 130  119   */
 131  120  int
 132  121  sogetvp(char *devpath, vnode_t **vpp, int uioflag)
 133  122  {
 134  123          struct snode *csp;
 135  124          vnode_t *vp, *dvp;
 136  125          major_t maj;
↓ open down ↓ 295 lines elided ↑ open up ↑
 432  421  /*
 433  422   * Return the AF_UNIX underlying filesystem vnode matching a given name.
 434  423   * Makes sure the sending and the destination sonodes are compatible.
 435  424   * The vnode is returned held.
 436  425   *
 437  426   * The underlying filesystem VSOCK vnode has a v_stream pointer that
 438  427   * references the actual stream head (hence indirectly the actual sonode).
 439  428   */
 440  429  static int
 441  430  so_ux_lookup(struct sonode *so, struct sockaddr_un *soun, int checkaccess,
 442      -                vnode_t **vpp)
      431 +    vnode_t **vpp)
 443  432  {
 444  433          vnode_t         *vp;    /* Underlying filesystem vnode */
 445  434          vnode_t         *rvp;   /* real vnode */
 446  435          vnode_t         *svp;   /* sockfs vnode */
 447  436          struct sonode   *so2;
 448  437          int             error;
 449  438  
 450  439          dprintso(so, 1, ("so_ux_lookup(%p) name <%s>\n", (void *)so,
 451  440              soun->sun_path));
 452  441  
↓ open down ↓ 306 lines elided ↑ open up ↑
 759  748                   * the option headers and values are only 4 bytes
 760  749                   * aligned. So its safer to do a bcopy compared to
 761  750                   * assigning fdbuf->fd_fds[i] to fp.
 762  751                   */
 763  752                  bcopy((char *)&fdbuf->fd_fds[i], (char *)&fp, sizeof (fp));
 764  753                  mutex_enter(&fp->f_tlock);
 765  754                  fp->f_count++;
 766  755                  mutex_exit(&fp->f_tlock);
 767  756                  setf(fd, fp);
 768  757                  *rp++ = fd;
      758 +
      759 +                /*
      760 +                 * Add the current pid to the list associated with this
      761 +                 * descriptor.
      762 +                 */
      763 +                if (fp->f_vnode != NULL)
      764 +                        (void) VOP_IOCTL(fp->f_vnode, F_ASSOCI_PID,
      765 +                            (intptr_t)curproc->p_pidp->pid_id, FKIOCTL, kcred,
      766 +                            NULL, NULL);
      767 +
 769  768                  if (AU_AUDITING())
 770  769                          audit_fdrecv(fd, fp);
 771  770                  dprint(1, ("fdbuf_extract: [%d] = %d, %p refcnt %d\n",
 772  771                      i, fd, (void *)fp, fp->f_count));
 773  772          }
 774  773          return (0);
 775  774  
 776  775  cleanup:
 777  776          /*
 778  777           * Undo whatever partial work the loop above has done.
↓ open down ↓ 960 lines elided ↑ open up ↑
1739 1738   * for the same zone, or sockfs_snapshot will be taken into the wrong size
1740 1739   * buffer. This is safe, but if the buffer is too small, user will not be
1741 1740   * given details of all sockets. However, as this kstat has a ks_lock, kstat
1742 1741   * driver will keep it locked between the update and the snapshot, so no
1743 1742   * other process (zone) can currently get inbetween resulting in a wrong size
1744 1743   * buffer allocation.
1745 1744   */
1746 1745  static int
1747 1746  sockfs_update(kstat_t *ksp, int rw)
1748 1747  {
1749      -        uint_t  nactive = 0;            /* # of active AF_UNIX sockets  */
     1748 +        uint_t  n, nactive = 0;         /* # of active AF_UNIX sockets  */
     1749 +        uint_t  tsze  = 0;
1750 1750          struct sonode   *so;            /* current sonode on socklist   */
1751 1751          zoneid_t        myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private;
1752 1752  
1753 1753          ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid());
1754 1754  
1755 1755          if (rw == KSTAT_WRITE) {        /* bounce all writes            */
1756 1756                  return (EACCES);
1757 1757          }
1758 1758  
1759 1759          for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) {
1760 1760                  if (so->so_count != 0 && so->so_zoneid == myzoneid) {
     1761 +
1761 1762                          nactive++;
     1763 +
     1764 +                        mutex_enter(&so->so_pid_tree_lock);
     1765 +                        n = avl_numnodes(&so->so_pid_tree);
     1766 +                        mutex_exit(&so->so_pid_tree_lock);
     1767 +
     1768 +                        tsze += sizeof (struct sockinfo);
     1769 +                        tsze += (n > 1) ? ((n - 1) * sizeof (pid_t)) : 0;
1762 1770                  }
1763 1771          }
1764 1772          ksp->ks_ndata = nactive;
1765      -        ksp->ks_data_size = nactive * sizeof (struct k_sockinfo);
     1773 +        ksp->ks_data_size = tsze;
1766 1774  
1767 1775          return (0);
1768 1776  }
1769 1777  
1770 1778  static int
1771 1779  sockfs_snapshot(kstat_t *ksp, void *buf, int rw)
1772 1780  {
1773 1781          int                     ns;     /* # of sonodes we've copied    */
1774 1782          struct sonode           *so;    /* current sonode on socklist   */
1775      -        struct k_sockinfo       *pksi;  /* where we put sockinfo data   */
     1783 +        struct sockinfo         *psi;   /* where we put sockinfo data   */
1776 1784          t_uscalar_t             sn_len; /* soa_len                      */
1777 1785          zoneid_t                myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private;
1778 1786          sotpi_info_t            *sti;
1779 1787  
     1788 +        uint_t                          sze;
     1789 +        mblk_t                          *mblk;
     1790 +        conn_pid_info_t                 *cpi;
     1791 +
1780 1792          ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid());
1781 1793  
1782 1794          ksp->ks_snaptime = gethrtime();
1783 1795  
1784 1796          if (rw == KSTAT_WRITE) {        /* bounce all writes            */
1785 1797                  return (EACCES);
1786 1798          }
1787 1799  
1788 1800          /*
1789 1801           * for each sonode on the socklist, we massage the important
1790 1802           * info into buf, in k_sockinfo format.
1791 1803           */
1792      -        pksi = (struct k_sockinfo *)buf;
     1804 +        psi = (struct sockinfo *)buf;
1793 1805          ns = 0;
1794 1806          for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) {
1795 1807                  /* only stuff active sonodes and the same zone:         */
1796 1808                  if (so->so_count == 0 || so->so_zoneid != myzoneid) {
1797 1809                          continue;
1798 1810                  }
1799 1811  
     1812 +                mblk = so_get_sock_pid_mblk((sock_upper_handle_t)so);
     1813 +                if (mblk == NULL) {
     1814 +                        continue;
     1815 +                }
     1816 +                cpi = (conn_pid_info_t *)mblk->b_datap->db_base;
     1817 +                sze = sizeof (struct sockinfo);
     1818 +                sze += (cpi->cpi_pids_cnt > 1) ?
     1819 +                    ((cpi->cpi_pids_cnt - 1) * sizeof (pid_t)) : 0;
     1820 +
1800 1821                  /*
1801 1822                   * If the sonode was activated between the update and the
1802      -                 * snapshot, we're done - as this is only a snapshot.
     1823 +                 * snapshot, we're done - as this is only a snapshot. We need
     1824 +                 * to make sure that we have space for this sockinfo. In the
     1825 +                 * time window between the update and the snapshot, the size of
     1826 +                 * sockinfo may change, as new pids are added/removed to/from
     1827 +                 * the list. We have to take that into consideration and only
     1828 +                 * include the sockinfo if we have enough space. That means the
     1829 +                 * number of entries we return by snapshot might not equal the
     1830 +                 * the number of entries calculated by update.
1803 1831                   */
1804      -                if ((caddr_t)(pksi) >= (caddr_t)buf + ksp->ks_data_size) {
     1832 +                if (((caddr_t)(psi) + sze) >
     1833 +                    ((caddr_t)buf + ksp->ks_data_size)) {
1805 1834                          break;
1806 1835                  }
1807 1836  
1808 1837                  sti = SOTOTPI(so);
1809 1838                  /* copy important info into buf:                        */
1810      -                pksi->ks_si.si_size = sizeof (struct k_sockinfo);
1811      -                pksi->ks_si.si_family = so->so_family;
1812      -                pksi->ks_si.si_type = so->so_type;
1813      -                pksi->ks_si.si_flag = so->so_flag;
1814      -                pksi->ks_si.si_state = so->so_state;
1815      -                pksi->ks_si.si_serv_type = sti->sti_serv_type;
1816      -                pksi->ks_si.si_ux_laddr_sou_magic =
     1839 +                psi->si_size = sze;
     1840 +                psi->si_family = so->so_family;
     1841 +                psi->si_type = so->so_type;
     1842 +                psi->si_flag = so->so_flag;
     1843 +                psi->si_state = so->so_state;
     1844 +                psi->si_serv_type = sti->sti_serv_type;
     1845 +                psi->si_ux_laddr_sou_magic =
1817 1846                      sti->sti_ux_laddr.soua_magic;
1818      -                pksi->ks_si.si_ux_faddr_sou_magic =
     1847 +                psi->si_ux_faddr_sou_magic =
1819 1848                      sti->sti_ux_faddr.soua_magic;
1820      -                pksi->ks_si.si_laddr_soa_len = sti->sti_laddr.soa_len;
1821      -                pksi->ks_si.si_faddr_soa_len = sti->sti_faddr.soa_len;
1822      -                pksi->ks_si.si_szoneid = so->so_zoneid;
1823      -                pksi->ks_si.si_faddr_noxlate = sti->sti_faddr_noxlate;
     1849 +                psi->si_laddr_soa_len = sti->sti_laddr.soa_len;
     1850 +                psi->si_faddr_soa_len = sti->sti_faddr.soa_len;
     1851 +                psi->si_szoneid = so->so_zoneid;
     1852 +                psi->si_faddr_noxlate = sti->sti_faddr_noxlate;
     1853 +
1824 1854  
1825 1855                  mutex_enter(&so->so_lock);
1826 1856  
1827 1857                  if (sti->sti_laddr_sa != NULL) {
1828 1858                          ASSERT(sti->sti_laddr_sa->sa_data != NULL);
1829 1859                          sn_len = sti->sti_laddr_len;
1830 1860                          ASSERT(sn_len <= sizeof (short) +
1831      -                            sizeof (pksi->ks_si.si_laddr_sun_path));
     1861 +                            sizeof (psi->si_laddr_sun_path));
1832 1862  
1833      -                        pksi->ks_si.si_laddr_family =
     1863 +                        psi->si_laddr_family =
1834 1864                              sti->sti_laddr_sa->sa_family;
1835 1865                          if (sn_len != 0) {
1836 1866                                  /* AF_UNIX socket names are NULL terminated */
1837      -                                (void) strncpy(pksi->ks_si.si_laddr_sun_path,
     1867 +                                (void) strncpy(psi->si_laddr_sun_path,
1838 1868                                      sti->sti_laddr_sa->sa_data,
1839      -                                    sizeof (pksi->ks_si.si_laddr_sun_path));
1840      -                                sn_len = strlen(pksi->ks_si.si_laddr_sun_path);
     1869 +                                    sizeof (psi->si_laddr_sun_path));
     1870 +                                sn_len = strlen(psi->si_laddr_sun_path);
1841 1871                          }
1842      -                        pksi->ks_si.si_laddr_sun_path[sn_len] = 0;
     1872 +                        psi->si_laddr_sun_path[sn_len] = 0;
1843 1873                  }
1844 1874  
1845 1875                  if (sti->sti_faddr_sa != NULL) {
1846 1876                          ASSERT(sti->sti_faddr_sa->sa_data != NULL);
1847 1877                          sn_len = sti->sti_faddr_len;
1848 1878                          ASSERT(sn_len <= sizeof (short) +
1849      -                            sizeof (pksi->ks_si.si_faddr_sun_path));
     1879 +                            sizeof (psi->si_faddr_sun_path));
1850 1880  
1851      -                        pksi->ks_si.si_faddr_family =
     1881 +                        psi->si_faddr_family =
1852 1882                              sti->sti_faddr_sa->sa_family;
1853 1883                          if (sn_len != 0) {
1854      -                                (void) strncpy(pksi->ks_si.si_faddr_sun_path,
     1884 +                                (void) strncpy(psi->si_faddr_sun_path,
1855 1885                                      sti->sti_faddr_sa->sa_data,
1856      -                                    sizeof (pksi->ks_si.si_faddr_sun_path));
1857      -                                sn_len = strlen(pksi->ks_si.si_faddr_sun_path);
     1886 +                                    sizeof (psi->si_faddr_sun_path));
     1887 +                                sn_len = strlen(psi->si_faddr_sun_path);
1858 1888                          }
1859      -                        pksi->ks_si.si_faddr_sun_path[sn_len] = 0;
     1889 +                        psi->si_faddr_sun_path[sn_len] = 0;
1860 1890                  }
1861 1891  
1862 1892                  mutex_exit(&so->so_lock);
1863 1893  
1864      -                (void) sprintf(pksi->ks_straddr[0], "%p", (void *)so);
1865      -                (void) sprintf(pksi->ks_straddr[1], "%p",
     1894 +                (void) sprintf(psi->si_son_straddr, "%p", (void *)so);
     1895 +                (void) sprintf(psi->si_lvn_straddr, "%p",
1866 1896                      (void *)sti->sti_ux_laddr.soua_vp);
1867      -                (void) sprintf(pksi->ks_straddr[2], "%p",
     1897 +                (void) sprintf(psi->si_fvn_straddr, "%p",
1868 1898                      (void *)sti->sti_ux_faddr.soua_vp);
1869 1899  
     1900 +                psi->si_pids[0] = 0;
     1901 +                if ((psi->si_pn_cnt = cpi->cpi_pids_cnt) > 0) {
     1902 +                        (void) memcpy(psi->si_pids, cpi->cpi_pids,
     1903 +                            psi->si_pn_cnt * sizeof (pid_t));
     1904 +                }
     1905 +
     1906 +                freemsg(mblk);
     1907 +
     1908 +                psi = (struct sockinfo *)((caddr_t)psi + psi->si_size);
1870 1909                  ns++;
1871      -                pksi++;
1872 1910          }
1873 1911  
1874 1912          ksp->ks_ndata = ns;
1875 1913          return (0);
1876 1914  }
1877 1915  
1878 1916  ssize_t
1879 1917  soreadfile(file_t *fp, uchar_t *buf, u_offset_t fileoff, int *err, size_t size)
1880 1918  {
1881 1919          struct uio auio;
↓ open down ↓ 68 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX