From owner-p4-projects@FreeBSD.ORG Fri Jun 26 03:42:47 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 59AE71065674; Fri, 26 Jun 2009 03:42:46 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0ED28106566C for ; Fri, 26 Jun 2009 03:42:46 +0000 (UTC) (envelope-from pgj@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id E75488FC0A for ; Fri, 26 Jun 2009 03:42:45 +0000 (UTC) (envelope-from pgj@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5Q3gjkp035847 for ; Fri, 26 Jun 2009 03:42:45 GMT (envelope-from pgj@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5Q3gjOh035845 for perforce@freebsd.org; Fri, 26 Jun 2009 03:42:45 GMT (envelope-from pgj@FreeBSD.org) Date: Fri, 26 Jun 2009 03:42:45 GMT Message-Id: <200906260342.n5Q3gjOh035845@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to pgj@FreeBSD.org using -f From: Gabor Pali To: Perforce Change Reviews Cc: Subject: PERFORCE change 165231 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Jun 2009 03:42:48 -0000 http://perforce.freebsd.org/chv.cgi?CH=165231 Change 165231 by pgj@petymeg-current on 2009/06/26 03:42:23 Introduce spcblist sysctl(8) variable for unix domain sockets, a stream format version of passing pcb lists from kernel to user applications. Affected files ... .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#35 edit .. //depot/projects/soc2009/pgj_libstat/src/sys/kern/uipc_usrreq.c#3 edit .. //depot/projects/soc2009/pgj_libstat/src/sys/sys/unpcb.h#3 edit Differences ... ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#35 (text+ko) ==== @@ -51,6 +51,7 @@ { "_tcbinfo", "_udbinfo", "_divcbinfo", "_ripcbinfo" }; static void extract_xunpcb_data(struct xunpcb *, struct socket_type *); +static void extract_unpcb_data(struct unpcb_data *, struct socket_type *); static void extract_inet_data(struct tcpcb *, struct inpcb *, struct xsocket *, struct socket_type *); @@ -75,15 +76,19 @@ net_local_pcblist_sysctl(int family, int type, struct socket_type_list *list, __unused int flags) { - char *buf; + char *buf, *p; size_t len; char mibvar[64]; - struct xunpgen *xug, *oxug; - struct xunpcb *xunp; + int count, i; + unp_gen_t gencnt; + + struct unpcb_stream *usp; + struct unpcb_data *udp; struct socket_type *stp; - sprintf(mibvar, "net.local.%s.pcblist", socktype[type]); + /* XXX: Should "spcblist" be renamed to "pcblist"? */ + sprintf(mibvar, "net.local.%s.spcblist", socktype[type]); len = 0; if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { @@ -100,20 +105,36 @@ free(buf); return (-2); } + if (len < sizeof(*usp)) { + list->stl_error = NETSTAT_ERROR_VERSION; + free(buf); + return (-2); + } + + p = buf; + usp = (struct unpcb_stream *)p; + p += sizeof(*usp); + + if (usp->us_version != UNPCB_STREAM_VERSION) { + list->stl_error = NETSTAT_ERROR_VERSION; + free(buf); + return (-1); + } - oxug = xug = (struct xunpgen *)buf; - for (xug = (struct xunpgen *)((char *)xug + xug->xug_len); - xug->xug_len > sizeof(struct xunpgen); - xug = (struct xunpgen *)((char *)xug + xug->xug_len)) { - xunp = (struct xunpcb *)xug; + count = usp->us_count; + gencnt = usp->us_gencnt; + + for (i = 0; i < count; i++) { + udp = (struct unpcb_data *)p; + p += sizeof(*udp); /* Keep active PCBs only. */ - if (xunp->xu_unp.unp_gencnt <= oxug->xug_gen) { + if (udp->ud_gencnt <= usp->us_gencnt) { stp = _netstat_st_allocate(list, family, type, socktype[type]); - extract_xunpcb_data(xunp, stp); + extract_unpcb_data(udp, stp); } } - + free(buf); return (0); } @@ -234,7 +255,6 @@ #define KREAD(off, buf, len) do { \ if (kread(kvm, (uintptr_t)(off), (buf), (len)) != 0) { \ - list->stl_error = NETSTAT_ERROR_UNDEFINED; \ return (-1); \ } \ } while (0); @@ -396,7 +416,6 @@ #define NPCB_KVM(proc, family, type, list, kvm, nl, flags) do { \ if (net_##proc##_pcblist_kvm((family), (type), (list), (kvm), (nl), \ (flags)) != 0) { \ - list->stl_error = NETSTAT_ERROR_UNDEFINED; \ return (-1); \ } \ } while (0) @@ -404,7 +423,6 @@ #define NPCB_SCT(proc, family, type, list, flags) do { \ if (net_##proc##_pcblist_sysctl((family), (type), (list), \ (flags)) != 0) { \ - list->stl_error = NETSTAT_ERROR_UNDEFINED; \ return (-1); \ } \ } while (0) @@ -619,6 +637,46 @@ } void +extract_unpcb_data(struct unpcb_data *udp, struct socket_type *stp) +{ + strlcpy(stp->st_extname, stp->st_name, SOCKTYPE_MAXNAME); + stp->st_qlen = udp->ud_qlen; + stp->st_incqlen = udp->ud_incqlen; + stp->st_qlimit = udp->ud_qlimit; + stp->st_snd.sbt_cc = udp->ud_snd_cc; + stp->st_snd.sbt_mcnt = udp->ud_snd_mcnt; + stp->st_snd.sbt_ccnt = udp->ud_snd_ccnt; + stp->st_snd.sbt_hiwat = udp->ud_snd_hiwat; + stp->st_snd.sbt_lowat = udp->ud_snd_lowat; + stp->st_snd.sbt_mbcnt = udp->ud_snd_mbcnt; + stp->st_snd.sbt_mbmax = udp->ud_snd_mbmax; + stp->st_rcv.sbt_cc = udp->ud_rcv_cc; + stp->st_rcv.sbt_mcnt = udp->ud_rcv_mcnt; + stp->st_rcv.sbt_ccnt = udp->ud_rcv_ccnt; + stp->st_rcv.sbt_hiwat = udp->ud_rcv_hiwat; + stp->st_rcv.sbt_lowat = udp->ud_rcv_lowat; + stp->st_rcv.sbt_mbcnt = udp->ud_rcv_mbcnt; + stp->st_rcv.sbt_mbmax = udp->ud_rcv_mbmax; + stp->st_pcb = udp->ud_pcb; + stp->st_vnode = udp->ud_vnode; + stp->st_conn = udp->ud_conn; + stp->st_refs = udp->ud_refs; + stp->st_reflink = udp->ud_reflink; + stp->st_flags = SOCKTYPE_VNODE | SOCKTYPE_CONN | SOCKTYPE_REFS; + stp->st_addrcnt = 0; + if (udp->ud_address_len > 0) { + stp->st_address[stp->st_addrcnt] = + _netstat_at_allocate(stp, NETSTAT_ADDRTYPE_LOCAL, + udp->ud_address, NULL, 0); + stp->st_address[stp->st_addrcnt]->at_port = 0; + strcpy(stp->st_address[stp->st_addrcnt]->at_portname, "*"); + stp->st_address[stp->st_addrcnt]->at_numeric[0] = '\0'; + stp->st_addrcnt += 1; + } + stp->st_tcpstate[0] = '\0'; +} + +void extract_inet_data(struct tcpcb *tp, struct inpcb *inp, struct xsocket *so, struct socket_type *stp) { ==== //depot/projects/soc2009/pgj_libstat/src/sys/kern/uipc_usrreq.c#3 (text+ko) ==== @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include @@ -79,6 +80,7 @@ #include #include #include +#include #include #include #include @@ -1485,6 +1487,125 @@ (caddr_t)(long)SOCK_STREAM, 0, unp_pcblist, "S,xunpcb", "List of active local stream sockets"); +static int +unp_spcblist(SYSCTL_HANDLER_ARGS) +{ + struct unpcb_stream us; + struct unpcb_data ud; + struct sbuf sbuf; + int error, i, buflen; + int freeunp; + char *buffer; + + struct unpcb *unp, **unp_list; + struct unp_head *head; + struct socket *sock; + + error = 0; + head = ((intptr_t)arg1 == SOCK_DGRAM ? &unp_dhead : &unp_shead); + + bzero(&us, sizeof(us)); + us.us_version = UNPCB_STREAM_VERSION; + + UNP_LIST_LOCK(); + us.us_gencnt = unp_gencnt; + us.us_count = unp_count; + UNP_LIST_UNLOCK(); + + unp_list = malloc(us.us_count * sizeof(*unp_list), M_TEMP, M_WAITOK); + + UNP_LIST_LOCK(); + for (unp = LIST_FIRST(head), i = 0; (unp != NULL) && (i < us.us_count); + unp = LIST_NEXT(unp, unp_link)) { + UNP_PCB_LOCK(unp); + if (unp->unp_gencnt <= us.us_gencnt) { + if (cr_cansee(req->td->td_ucred, + unp->unp_socket->so_cred) == 0) { + unp_list[i++] = unp; + unp->unp_refcount++; + } + } + UNP_PCB_UNLOCK(unp); + } + UNP_LIST_UNLOCK(); + us.us_count = i; + + buflen = sizeof(us) + us.us_count * sizeof(ud) + 1; + buffer = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO); + sbuf_new(&sbuf, buffer, buflen, SBUF_FIXEDLEN); + + if (sbuf_bcat(&sbuf, &us, sizeof(us)) < 0) { + error = ENOMEM; + goto out; + } + + for (i = 0; i < us.us_count; i++) { + unp = unp_list[i]; + UNP_PCB_LOCK(unp); + unp->unp_refcount--; + if (unp->unp_refcount != 0 && unp->unp_gencnt <= us.us_gencnt) { + bzero(&ud, sizeof(ud)); + sock = unp->unp_socket; + ud.ud_gencnt = unp->unp_gencnt; + ud.ud_qlen = sock->so_qlen; + ud.ud_incqlen = sock->so_incqlen; + ud.ud_qlimit = sock->so_qlimit; + ud.ud_snd_cc = sock->so_snd.sb_cc; + ud.ud_snd_mcnt = sock->so_snd.sb_mcnt; + ud.ud_snd_ccnt = sock->so_snd.sb_ccnt; + ud.ud_snd_hiwat = sock->so_snd.sb_hiwat; + ud.ud_snd_lowat = sock->so_snd.sb_lowat; + ud.ud_snd_mbcnt = sock->so_snd.sb_mbcnt; + ud.ud_snd_mbmax = sock->so_snd.sb_mbmax; + ud.ud_rcv_cc = sock->so_rcv.sb_cc; + ud.ud_rcv_mcnt = sock->so_rcv.sb_mcnt; + ud.ud_rcv_ccnt = sock->so_rcv.sb_ccnt; + ud.ud_rcv_hiwat = sock->so_rcv.sb_hiwat; + ud.ud_rcv_lowat = sock->so_rcv.sb_lowat; + ud.ud_rcv_mbcnt = sock->so_rcv.sb_mbcnt; + ud.ud_rcv_mbmax = sock->so_rcv.sb_mbmax; + ud.ud_pcb = (u_long)sock->so_pcb; + ud.ud_vnode = (u_long)unp->unp_vnode; + ud.ud_conn = (u_long)unp->unp_conn; + ud.ud_refs = (u_long)LIST_FIRST(&unp->unp_refs); + ud.ud_reflink = (u_long)LIST_NEXT(unp, unp_reflink); + ud.ud_address_len = (unp->unp_addr != NULL) ? + unp->unp_addr->sun_len : 0; + if (ud.ud_address_len > 0) { + bcopy(ud.ud_address, unp->unp_addr, + ud.ud_address_len); + } + UNP_PCB_UNLOCK(unp); + if (sbuf_bcat(&sbuf, &ud, sizeof(ud)) < 0) { + error = ENOMEM; + goto uout; + } + } else { + freeunp = (unp->unp_refcount == 0); + UNP_PCB_UNLOCK(unp); + if (freeunp) { + UNP_PCB_LOCK_DESTROY(unp); + uma_zfree(unp_zone, unp); + } + } + } + sbuf_finish(&sbuf); + error = SYSCTL_OUT(req, sbuf_data(&sbuf), sbuf_len(&sbuf)); +uout: + free(unp_list, M_TEMP); +out: + free(buffer, M_TEMP); + return (error); +} + +SYSCTL_PROC(_net_local_dgram, OID_AUTO, spcblist, CTLFLAG_RD|CTLTYPE_STRUCT, + (caddr_t)(long)SOCK_DGRAM, 0, unp_spcblist, "s,struct unpcb_data", + "List of active local datagram sockets (stream)"); + +SYSCTL_PROC(_net_local_stream, OID_AUTO, spcblist, CTLFLAG_RD|CTLTYPE_STRUCT, + (caddr_t)(long)SOCK_STREAM, 0, unp_spcblist, "s,struct unpcb_data", + "List of active local stream sockets (stream)"); + static void unp_shutdown(struct unpcb *unp) { ==== //depot/projects/soc2009/pgj_libstat/src/sys/sys/unpcb.h#3 (text+ko) ==== @@ -151,27 +151,17 @@ #define UNPCB_STREAM_VERSION 0x00000001 -/* - * Stream structure: - * (unpcb_stream) (unpcb_gen) (unpcb_data [unpcb_address]) ... (unpcb_gen) - * - */ - struct unpcb_stream { u_int32_t us_version; /* Stream format version. */ - u_int32_t us_count; /* Number of records. */ - u_int32_t _us_pad[2]; /* Padding. */ + u_int32_t us_count; + u_int64_t us_gencnt; }; -struct unpcb_gen { - u_int64_t ug_gen; - u_int64_t ug_sogen; - u_int64_t _ug_pad[6]; -}; - /* Exported data for user applications (not complete) */ struct unpcb_data { - uint16_t ud_address_len; /* 0: no address associated. */ + u_int64_t ud_gencnt; + uint8_t ud_address_len; + char ud_address[104]; uint16_t ud_qlen; uint16_t ud_incqlen; uint16_t ud_qlimit; @@ -194,7 +184,6 @@ u_int64_t ud_conn; u_int64_t ud_refs; u_int64_t ud_reflink; - uint16_t _ud_pad[22]; }; #endif /* _SYS_UNPCB_H_ */