From owner-freebsd-hackers Mon May 17 23: 8:34 1999 Delivered-To: freebsd-hackers@freebsd.org Received: from cygnus.rush.net (cygnus.rush.net [209.45.245.133]) by hub.freebsd.org (Postfix) with ESMTP id 2D87D151CE for ; Mon, 17 May 1999 23:08:31 -0700 (PDT) (envelope-from bright@rush.net) Received: from localhost (bright@localhost) by cygnus.rush.net (8.9.3/8.9.3) with SMTP id BAA18297; Tue, 18 May 1999 01:33:05 -0500 (EST) Date: Tue, 18 May 1999 01:33:01 -0500 (EST) From: Alfred Perlstein To: Marc Slemko Cc: hackers@FreeBSD.ORG Subject: so use sysctl (was: Re: libkvm sucks) In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Mon, 17 May 1999, Marc Slemko wrote: > The premise: libkvm is fatally flawed by design, and fixing it is not an > easy proposition. > > The reasoning: reading from kernel data structures without any locking has > obvious race conditions. > > This is why any identd that uses libkvm sucks and gets into loops all the > time, etc. > > This is why netstat will often bail out in the middle with kvm errors on a > busy machine with lots of TCP connections, especially if you slow it down > by doing hostname lookups. > > In fact, on BSDI systems I have even seen identd hang the entire machine > hard by reading from the wrong address that the IO APIC is mapped at (BSDI > maps it starting at 0xffff0000, which much worse than a random address > for accidental reads). > > In general, I'm no fan of the Linux style proc (by "Linux style" I mean > going crazy with the types of info there and the huge amount of formatting > done in the kernel), but in this case it can work a whole lot better, even > if it is somewhat less efficient. > > I'm sure this isn't a new problem, but I don't recall hearing of any > suggested solutions and I'm not aware of any alternative interface to get > the same info on FreeBSD. Anyone? unf! part of a multithreaded ident server that i got bored with... i'm not entirely sure it still works: uid_t get_sok_uid(u_short lport, u_short fport, int *err){ /* mostly stolen from netstat */ char *mibvar = "net.inet.tcp.pcblist"; char *buf; int proto = IPPROTO_TCP; uid_t retval = 0; struct tcpcb *tp; struct inpcb *inp; struct xinpgen *xig, *oxig; struct xsocket *so; size_t len = 0; *err = NO_ERR; if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { *err = ERR_SYSCTL; return(0); } if ((buf = (char *) malloc(len)) == 0) { *err = ERR_MALLOC; return(0); } if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) { *err = ERR_SYSCTL; free(buf); return(0); } oxig = xig = (struct xinpgen *)buf; for (xig = (struct xinpgen *)((char *)xig + xig->xig_len); xig->xig_len > sizeof(struct xinpgen); xig = (struct xinpgen *)((char *)xig + xig->xig_len)) { tp = &((struct xtcpcb *)xig)->xt_tp; inp = &((struct xtcpcb *)xig)->xt_inp; so = &((struct xtcpcb *)xig)->xt_socket; /* Ignore sockets for protocols other than the desired one. */ if (so->xso_protocol != proto) continue; /* Ignore PCBs which were freed during copyout. */ if (inp->inp_gencnt > oxig->xig_gen) continue; /* check port */ if ( htons(inp->inp_fport) == fport && htons(inp->inp_lport) == lport){ printf("pgid = %d\n", so->so_pgid); retval = so->so_uid; free(buf); return( retval ); } } *err = ERR_NOUSER; free(buf); } enjoy, -Alfred To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message