Print this page
XXXX adding PID information to netstat output

*** 111,131 **** extern void nl7c_init(void); extern int modrootloaded; - #define ADRSTRLEN (2 * sizeof (void *) + 1) - /* - * kernel structure for passing the sockinfo data back up to the user. - * the strings array allows us to convert AF_UNIX addresses into strings - * with a common method regardless of which n-bit kernel we're running. - */ - struct k_sockinfo { - struct sockinfo ks_si; - char ks_straddr[3][ADRSTRLEN]; - }; - /* * Translate from a device pathname (e.g. "/dev/tcp") to a vnode. * Returns with the vnode held. */ int --- 111,120 ----
*** 764,773 **** --- 753,767 ---- mutex_enter(&fp->f_tlock); fp->f_count++; mutex_exit(&fp->f_tlock); setf(fd, fp); *rp++ = fd; + /* add curproc to the pid list associated with that file */ + if (fp->f_vnode != NULL) + (void) VOP_IOCTL(fp->f_vnode, F_FORKED, + (intptr_t)curproc, FKIOCTL, kcred, NULL, NULL); + if (AU_AUDITING()) audit_fdrecv(fd, fp); dprint(1, ("fdbuf_extract: [%d] = %d, %p refcnt %d\n", i, fd, (void *)fp, fp->f_count)); }
*** 1741,1784 **** * given details of all sockets. However, as this kstat has a ks_lock, kstat * driver will keep it locked between the update and the snapshot, so no * other process (zone) can currently get inbetween resulting in a wrong size * buffer allocation. */ static int sockfs_update(kstat_t *ksp, int rw) { ! uint_t nactive = 0; /* # of active AF_UNIX sockets */ struct sonode *so; /* current sonode on socklist */ zoneid_t myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private; ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid()); if (rw == KSTAT_WRITE) { /* bounce all writes */ return (EACCES); } for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) { if (so->so_count != 0 && so->so_zoneid == myzoneid) { nactive++; } } ksp->ks_ndata = nactive; ! ksp->ks_data_size = nactive * sizeof (struct k_sockinfo); return (0); } static int sockfs_snapshot(kstat_t *ksp, void *buf, int rw) { int ns; /* # of sonodes we've copied */ struct sonode *so; /* current sonode on socklist */ ! struct k_sockinfo *pksi; /* where we put sockinfo data */ t_uscalar_t sn_len; /* soa_len */ zoneid_t myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private; sotpi_info_t *sti; ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid()); ksp->ks_snaptime = gethrtime(); if (rw == KSTAT_WRITE) { /* bounce all writes */ --- 1735,1795 ---- * given details of all sockets. However, as this kstat has a ks_lock, kstat * driver will keep it locked between the update and the snapshot, so no * other process (zone) can currently get inbetween resulting in a wrong size * buffer allocation. */ + static int sockfs_update(kstat_t *ksp, int rw) { ! uint_t n, nactive = 0; /* # of active AF_UNIX sockets */ ! uint_t tsze, sze; struct sonode *so; /* current sonode on socklist */ zoneid_t myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private; + tsze = sze = 0; + ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid()); if (rw == KSTAT_WRITE) { /* bounce all writes */ return (EACCES); } for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) { if (so->so_count != 0 && so->so_zoneid == myzoneid) { + nactive++; + + mutex_enter(&so->so_pid_list_lock); + n = list_size(&so->so_pid_list); + mutex_exit(&so->so_pid_list_lock); + + sze = sizeof (struct sockinfo); + sze += (n > 1)?((n - 1) * sizeof (conn_pid_node_t)):0; + tsze += sze; + } } ksp->ks_ndata = nactive; ! ksp->ks_data_size = tsze; return (0); } static int sockfs_snapshot(kstat_t *ksp, void *buf, int rw) { int ns; /* # of sonodes we've copied */ struct sonode *so; /* current sonode on socklist */ ! struct sockinfo *psi; /* where we put sockinfo data */ t_uscalar_t sn_len; /* soa_len */ zoneid_t myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private; sotpi_info_t *sti; + uint_t sze; + conn_pid_node_list_hdr_t *cph; + ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid()); ksp->ks_snaptime = gethrtime(); if (rw == KSTAT_WRITE) { /* bounce all writes */
*** 1787,1876 **** /* * for each sonode on the socklist, we massage the important * info into buf, in k_sockinfo format. */ ! pksi = (struct k_sockinfo *)buf; ns = 0; for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) { /* only stuff active sonodes and the same zone: */ if (so->so_count == 0 || so->so_zoneid != myzoneid) { continue; } /* * If the sonode was activated between the update and the ! * snapshot, we're done - as this is only a snapshot. */ ! if ((caddr_t)(pksi) >= (caddr_t)buf + ksp->ks_data_size) { break; } sti = SOTOTPI(so); /* copy important info into buf: */ ! pksi->ks_si.si_size = sizeof (struct k_sockinfo); ! pksi->ks_si.si_family = so->so_family; ! pksi->ks_si.si_type = so->so_type; ! pksi->ks_si.si_flag = so->so_flag; ! pksi->ks_si.si_state = so->so_state; ! pksi->ks_si.si_serv_type = sti->sti_serv_type; ! pksi->ks_si.si_ux_laddr_sou_magic = sti->sti_ux_laddr.soua_magic; ! pksi->ks_si.si_ux_faddr_sou_magic = sti->sti_ux_faddr.soua_magic; ! pksi->ks_si.si_laddr_soa_len = sti->sti_laddr.soa_len; ! pksi->ks_si.si_faddr_soa_len = sti->sti_faddr.soa_len; ! pksi->ks_si.si_szoneid = so->so_zoneid; ! pksi->ks_si.si_faddr_noxlate = sti->sti_faddr_noxlate; mutex_enter(&so->so_lock); if (sti->sti_laddr_sa != NULL) { ASSERT(sti->sti_laddr_sa->sa_data != NULL); sn_len = sti->sti_laddr_len; ASSERT(sn_len <= sizeof (short) + ! sizeof (pksi->ks_si.si_laddr_sun_path)); ! pksi->ks_si.si_laddr_family = sti->sti_laddr_sa->sa_family; if (sn_len != 0) { /* AF_UNIX socket names are NULL terminated */ ! (void) strncpy(pksi->ks_si.si_laddr_sun_path, sti->sti_laddr_sa->sa_data, ! sizeof (pksi->ks_si.si_laddr_sun_path)); ! sn_len = strlen(pksi->ks_si.si_laddr_sun_path); } ! pksi->ks_si.si_laddr_sun_path[sn_len] = 0; } if (sti->sti_faddr_sa != NULL) { ASSERT(sti->sti_faddr_sa->sa_data != NULL); sn_len = sti->sti_faddr_len; ASSERT(sn_len <= sizeof (short) + ! sizeof (pksi->ks_si.si_faddr_sun_path)); ! pksi->ks_si.si_faddr_family = sti->sti_faddr_sa->sa_family; if (sn_len != 0) { ! (void) strncpy(pksi->ks_si.si_faddr_sun_path, sti->sti_faddr_sa->sa_data, ! sizeof (pksi->ks_si.si_faddr_sun_path)); ! sn_len = strlen(pksi->ks_si.si_faddr_sun_path); } ! pksi->ks_si.si_faddr_sun_path[sn_len] = 0; } mutex_exit(&so->so_lock); ! (void) sprintf(pksi->ks_straddr[0], "%p", (void *)so); ! (void) sprintf(pksi->ks_straddr[1], "%p", (void *)sti->sti_ux_laddr.soua_vp); ! (void) sprintf(pksi->ks_straddr[2], "%p", (void *)sti->sti_ux_faddr.soua_vp); ns++; - pksi++; } ksp->ks_ndata = ns; return (0); } --- 1798,1904 ---- /* * for each sonode on the socklist, we massage the important * info into buf, in k_sockinfo format. */ ! psi = (struct sockinfo *)buf; ns = 0; for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) { /* only stuff active sonodes and the same zone: */ if (so->so_count == 0 || so->so_zoneid != myzoneid) { continue; } + /* get the pidnode list associated with this sonode */ + cph = so_get_sock_pid_list((sock_upper_handle_t)so); + + /* calculate the size of this sockinfo structure */ + sze = sizeof (struct sockinfo); + sze += (cph->cph_pn_cnt > 1)? + ((cph->cph_pn_cnt - 1) * sizeof (conn_pid_node_t)):0; + /* * If the sonode was activated between the update and the ! * snapshot, we're done - as this is only a snapshot. We need ! * to make sure that we have space for this sockinfo. */ ! if (((caddr_t)(psi) + sze) > ! ((caddr_t)buf + ksp->ks_data_size)) { break; } sti = SOTOTPI(so); /* copy important info into buf: */ ! psi->si_size = sze; ! psi->si_family = so->so_family; ! psi->si_type = so->so_type; ! psi->si_flag = so->so_flag; ! psi->si_state = so->so_state; ! psi->si_serv_type = sti->sti_serv_type; ! psi->si_ux_laddr_sou_magic = sti->sti_ux_laddr.soua_magic; ! psi->si_ux_faddr_sou_magic = sti->sti_ux_faddr.soua_magic; ! psi->si_laddr_soa_len = sti->sti_laddr.soa_len; ! psi->si_faddr_soa_len = sti->sti_faddr.soa_len; ! psi->si_szoneid = so->so_zoneid; ! psi->si_faddr_noxlate = sti->sti_faddr_noxlate; ! mutex_enter(&so->so_lock); if (sti->sti_laddr_sa != NULL) { ASSERT(sti->sti_laddr_sa->sa_data != NULL); sn_len = sti->sti_laddr_len; ASSERT(sn_len <= sizeof (short) + ! sizeof (psi->si_laddr_sun_path)); ! psi->si_laddr_family = sti->sti_laddr_sa->sa_family; if (sn_len != 0) { /* AF_UNIX socket names are NULL terminated */ ! (void) strncpy(psi->si_laddr_sun_path, sti->sti_laddr_sa->sa_data, ! sizeof (psi->si_laddr_sun_path)); ! sn_len = strlen(psi->si_laddr_sun_path); } ! psi->si_laddr_sun_path[sn_len] = 0; } if (sti->sti_faddr_sa != NULL) { ASSERT(sti->sti_faddr_sa->sa_data != NULL); sn_len = sti->sti_faddr_len; ASSERT(sn_len <= sizeof (short) + ! sizeof (psi->si_faddr_sun_path)); ! psi->si_faddr_family = sti->sti_faddr_sa->sa_family; if (sn_len != 0) { ! (void) strncpy(psi->si_faddr_sun_path, sti->sti_faddr_sa->sa_data, ! sizeof (psi->si_faddr_sun_path)); ! sn_len = strlen(psi->si_faddr_sun_path); } ! psi->si_faddr_sun_path[sn_len] = 0; } mutex_exit(&so->so_lock); ! (void) sprintf(psi->si_son_straddr, "%p", (void *)so); ! (void) sprintf(psi->si_lvn_straddr, "%p", (void *)sti->sti_ux_laddr.soua_vp); ! (void) sprintf(psi->si_fvn_straddr, "%p", (void *)sti->sti_ux_faddr.soua_vp); + if ((psi->si_pn_cnt = cph->cph_pn_cnt) > 0) + (void) memcpy(psi->si_pns, cph->cph_cpns, + psi->si_pn_cnt * sizeof (conn_pid_node_t)); + + kmem_free(cph, cph->cph_tot_size); + + psi = (struct sockinfo *)((char *)psi + psi->si_size); ns++; } ksp->ks_ndata = ns; return (0); }