From: Kalin KOZHUHAROV <kalin@ThinRope.net>
To: Linus Torvalds <torvalds@osdl.org>
Cc: Davide Libenzi <davidel@xmailserver.org>,
Robert Love <rml@ximian.com>, Chris Wedgwood <cw@f00f.org>,
Arjan van de Ven <arjanv@redhat.com>,
Russell Leighton <russ@elegant-software.com>,
Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: clone() <-> getpid() bug in 2.6?
Date: Sun, 06 Jun 2004 14:08:52 +0900 [thread overview]
Message-ID: <40C2A6E4.7020103@ThinRope.net> (raw)
In-Reply-To: <Pine.LNX.4.58.0406051610430.7010@ppc970.osdl.org>
[-- Attachment #1: Type: text/plain, Size: 5604 bytes --]
Linus Torvalds wrote:
>
> On Sat, 5 Jun 2004, Davide Libenzi wrote:
>
>> It is likely used by pthread_self(), that is pretty much
>> performance sensitive. I'd agree with Ulrich here.
>
>
> It _can't_ be used for pthread_self(), since the pid is the _same_
> across all threads in a pthread environment.
>
> See?
>
> I re-iterate:
>
> - getpid() was used in some historical threading packages (maybe even
> LinuxThreads) to get the thread ID thing.
>
> But this particular usage requires the old Linux behaviour of
> returning separate threads ID's for separate threads. CLONE_THREAD
> does not do that, and in particular the glibc caching _breaks_ any
> such attempt even when you don't use CLONE_THREAD.
>
> pthreads() in modern libc sets CLONE_THREAD and then uses the
> per-thread segment thing to identify threads. No getpid() anywhere.
>
> Ergo: getpid() caching may result in faster execution, but in this
> case it's actively _wrong_, and breaks the app. It's easy to make
> things go fast if you don't actually care about whether the end
> result is correct or not.
>
> - getpid() is used in some silly benchmarks.
>
> But in this case caching getpid() just lies to the benchmark, and is
> pointless.
>
> Ergo: getpid() caching results in higher scores, but the scores are
> now meaningless, since they have nothing to do with system call speed
> any more.
>
> So in both of these cases, the caching literally results in WRONG
> behaviour.
>
> Can somebody actually find an application that doesn't fall into
> either of the above two categories, and calls getpid() more than a
> handful of times?
>
Well, not exactly sure about my reply, but let me try.
The other day I was debugging some config problems with my qmail instalation and I ended up doing:
# strace -p 4563 -f -F
...
[pid 13097] read(3, "\347\374\375TBH~\342\233\337\220\302l\220\317\237\37\25"..., 32) = 32
[pid 13097] close(3) = 0
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getuid32() = 89
[pid 13097] getpid() = 13097
[pid 13097] time(NULL) = 1086497450
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] time(NULL) = 1086497450
[pid 13097] getpid() = 13097
[pid 13097] getpid() = 13097
[pid 13097] write(0, "\26\3\1\0J\2\0\0F\3\1@\302\242\2527j\266m4{\323>6\232\243"..., 1127) = 1127
[pid 13097] read(0, "\26\3\1\1\6", 5) = 5
...
where 4563 is a tcpserver process and 13097 is its child. The process was started as:
tcpserver -s -n ssmtp.crt -p -v -R -x /etc/tcprules.d/tcp.smtp.cdb -c 40 -u 89 -g 89 0.0.0.0 465 /var/qmail/bin/qmail-smtpd mail.tar.bz /var/vpopmail/bin/vchkpw /bin/true
No idea why are all those getpid() call there in the child... Looked at the code, but couldn't get it. Attaching tcpserver.c for reference.
Again, sorry if unrelated.
Kalin.
--
||///_ o *****************************
||//'_/> WWW: http://ThinRope.net/
|||\/<"
|||\\ '
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[-- Attachment #2: tcpserver.c --]
[-- Type: text/plain, Size: 15039 bytes --]
#include <sys/types.h>
#include <sys/param.h>
#include <netdb.h>
#include <openssl/ssl.h>
#include "uint16.h"
#include "str.h"
#include "byte.h"
#include "fmt.h"
#include "scan.h"
#include "ip4.h"
#include "fd.h"
#include "exit.h"
#include "env.h"
#include "prot.h"
#include "open.h"
#include "wait.h"
#include "readwrite.h"
#include "stralloc.h"
#include "alloc.h"
#include "buffer.h"
#include "error.h"
#include "strerr.h"
#include "sgetopt.h"
#include "pathexec.h"
#include "socket.h"
#include "ndelay.h"
#include "remoteinfo.h"
#include "rules.h"
#include "sig.h"
#include "dns.h"
int verbosity = 1;
int flagkillopts = 1;
int flagdelay = 1;
char *banner = "";
int flagremoteinfo = 1;
int flagremotehost = 1;
int flagparanoid = 0;
unsigned long timeout = 26;
#ifdef WITH_SSL
int flagssl = 0;
struct stralloc certfile = {0};
#define CERTFILE "./cert.pem"
void translate(SSL*, int, int, unsigned int);
#endif
static stralloc tcpremoteinfo;
uint16 localport;
char localportstr[FMT_ULONG];
char localip[4];
char localipstr[IP4_FMT];
static stralloc localhostsa;
char *localhost = 0;
uint16 remoteport;
char remoteportstr[FMT_ULONG];
char remoteip[4];
char remoteipstr[IP4_FMT];
static stralloc remotehostsa;
char *remotehost = 0;
char strnum[FMT_ULONG];
char strnum2[FMT_ULONG];
static stralloc tmp;
static stralloc fqdn;
static stralloc addresses;
char bspace[16];
buffer b;
/* ---------------------------- child */
#define DROP "tcpserver: warning: dropping connection, "
int flagdeny = 0;
int flagallownorules = 0;
char *fnrules = 0;
void drop_nomem(void)
{
strerr_die2sys(111,DROP,"out of memory");
}
void cats(char *s)
{
if (!stralloc_cats(&tmp,s)) drop_nomem();
}
void append(char *ch)
{
if (!stralloc_append(&tmp,ch)) drop_nomem();
}
void safecats(char *s)
{
char ch;
int i;
for (i = 0;i < 100;++i) {
ch = s[i];
if (!ch) return;
if (ch < 33) ch = '?';
if (ch > 126) ch = '?';
if (ch == '%') ch = '?'; /* logger stupidity */
if (ch == ':') ch = '?';
append(&ch);
}
cats("...");
}
void env(char *s,char *t)
{
if (!pathexec_env(s,t)) drop_nomem();
}
void drop_rules(void)
{
strerr_die4sys(111,DROP,"unable to read ",fnrules,": ");
}
void found(char *data,unsigned int datalen)
{
unsigned int next0;
unsigned int split;
while ((next0 = byte_chr(data,datalen,0)) < datalen) {
switch(data[0]) {
case 'D':
flagdeny = 1;
break;
case '+':
split = str_chr(data + 1,'=');
if (data[1 + split] == '=') {
data[1 + split] = 0;
env(data + 1,data + 1 + split + 1);
}
break;
}
++next0;
data += next0; datalen -= next0;
}
}
void doit(int t)
{
int j;
remoteipstr[ip4_fmt(remoteipstr,remoteip)] = 0;
if (verbosity >= 2) {
strnum[fmt_ulong(strnum,getpid())] = 0;
strerr_warn4("tcpserver: pid ",strnum," from ",remoteipstr,0);
}
if (flagkillopts)
socket_ipoptionskill(t);
if (!flagdelay)
socket_tcpnodelay(t);
if (*banner) {
buffer_init(&b,write,t,bspace,sizeof bspace);
if (buffer_putsflush(&b,banner) == -1)
strerr_die2sys(111,DROP,"unable to print banner: ");
}
if (socket_local4(t,localip,&localport) == -1)
strerr_die2sys(111,DROP,"unable to get local address: ");
localipstr[ip4_fmt(localipstr,localip)] = 0;
remoteportstr[fmt_ulong(remoteportstr,remoteport)] = 0;
if (!localhost)
if (dns_name4(&localhostsa,localip) == 0)
if (localhostsa.len) {
if (!stralloc_0(&localhostsa)) drop_nomem();
localhost = localhostsa.s;
}
env("PROTO","TCP");
env("TCPLOCALIP",localipstr);
env("TCPLOCALPORT",localportstr);
env("TCPLOCALHOST",localhost);
if (flagremotehost)
if (dns_name4(&remotehostsa,remoteip) == 0)
if (remotehostsa.len) {
if (flagparanoid)
if (dns_ip4(&tmp,&remotehostsa) == 0)
for (j = 0;j + 4 <= tmp.len;j += 4)
if (byte_equal(remoteip,4,tmp.s + j)) {
flagparanoid = 0;
break;
}
if (!flagparanoid) {
if (!stralloc_0(&remotehostsa)) drop_nomem();
remotehost = remotehostsa.s;
}
}
env("TCPREMOTEIP",remoteipstr);
env("TCPREMOTEPORT",remoteportstr);
env("TCPREMOTEHOST",remotehost);
if (flagremoteinfo) {
if (remoteinfo(&tcpremoteinfo,remoteip,remoteport,localip,localport,timeout) == -1)
flagremoteinfo = 0;
if (!stralloc_0(&tcpremoteinfo)) drop_nomem();
}
env("TCPREMOTEINFO",flagremoteinfo ? tcpremoteinfo.s : 0);
if (fnrules) {
int fdrules;
fdrules = open_read(fnrules);
if (fdrules == -1) {
if (errno != error_noent) drop_rules();
if (!flagallownorules) drop_rules();
}
else {
if (rules(found,fdrules,remoteipstr,remotehost,flagremoteinfo ? tcpremoteinfo.s : 0) == -1) drop_rules();
close(fdrules);
}
}
if (verbosity >= 2) {
strnum[fmt_ulong(strnum,getpid())] = 0;
if (!stralloc_copys(&tmp,"tcpserver: ")) drop_nomem();
safecats(flagdeny ? "deny" : "ok");
cats(" "); safecats(strnum);
cats(" "); if (localhost) safecats(localhost);
cats(":"); safecats(localipstr);
cats(":"); safecats(localportstr);
cats(" "); if (remotehost) safecats(remotehost);
cats(":"); safecats(remoteipstr);
cats(":"); if (flagremoteinfo) safecats(tcpremoteinfo.s);
cats(":"); safecats(remoteportstr);
cats("\n");
buffer_putflush(buffer_2,tmp.s,tmp.len);
}
if (flagdeny) _exit(100);
}
/* ---------------------------- parent */
#define FATAL "tcpserver: fatal: "
void usage(void)
{
#ifndef WITH_SSL
strerr_warn1("\
tcpserver: usage: tcpserver \
[ -1UXpPhHrRoOdDqQv ] \
[ -c limit ] \
[ -x rules.cdb ] \
[ -B banner ] \
[ -g gid ] \
[ -u uid ] \
[ -b backlog ] \
[ -l localname ] \
[ -t timeout ] \
host port program",0);
#else
strerr_warn1("\
tcpserver: usage: tcpserver \
[ -1UXpPhHrRoOdDqQsSv ] \
[ -c limit ] \
[ -x rules.cdb ] \
[ -B banner ] \
[ -g gid ] \
[ -u uid ] \
[ -b backlog ] \
[ -l localname ] \
[ -t timeout ] \
[ -n certfile ] \
host port program",0);
#endif
_exit(100);
}
unsigned long limit = 40;
unsigned long numchildren = 0;
int flag1 = 0;
unsigned long backlog = 20;
unsigned long uid = 0;
unsigned long gid = 0;
void printstatus(void)
{
if (verbosity < 2) return;
strnum[fmt_ulong(strnum,numchildren)] = 0;
strnum2[fmt_ulong(strnum2,limit)] = 0;
strerr_warn4("tcpserver: status: ",strnum,"/",strnum2,0);
}
void sigterm()
{
_exit(0);
}
void sigchld()
{
int wstat;
int pid;
while ((pid = wait_nohang(&wstat)) > 0) {
if (verbosity >= 2) {
strnum[fmt_ulong(strnum,pid)] = 0;
strnum2[fmt_ulong(strnum2,wstat)] = 0;
strerr_warn4("tcpserver: end ",strnum," status ",strnum2,0);
}
if (numchildren) --numchildren; printstatus();
}
}
main(int argc,char **argv)
{
char *hostname;
char *portname;
int opt;
struct servent *se;
char *x;
unsigned long u;
int s;
int t;
#ifdef WITH_SSL
BIO *sbio;
SSL *ssl;
SSL_CTX *ctx;
int pi2c[2], pi4c[2];
ctx = NULL;
if (!stralloc_copys(&certfile, CERTFILE) || !stralloc_0(&certfile) )
strerr_die2x(111,FATAL,"out of memory");
while ((opt = getopt(argc,argv,"dDvqQhHrRsS1UXx:t:u:g:l:b:B:c:n:pPoO")) != opteof)
#else
while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx:t:u:g:l:b:B:c:pPoO")) != opteof)
#endif
switch(opt) {
case 'b': scan_ulong(optarg,&backlog); break;
case 'c': scan_ulong(optarg,&limit); break;
case 'X': flagallownorules = 1; break;
case 'x': fnrules = optarg; break;
case 'B': banner = optarg; break;
case 'd': flagdelay = 1; break;
case 'D': flagdelay = 0; break;
case 'v': verbosity = 2; break;
case 'q': verbosity = 0; break;
case 'Q': verbosity = 1; break;
case 'P': flagparanoid = 0; break;
case 'p': flagparanoid = 1; break;
case 'O': flagkillopts = 1; break;
case 'o': flagkillopts = 0; break;
case 'H': flagremotehost = 0; break;
case 'h': flagremotehost = 1; break;
case 'R': flagremoteinfo = 0; break;
case 'r': flagremoteinfo = 1; break;
case 't': scan_ulong(optarg,&timeout); break;
case 'U': x = env_get("UID"); if (x) scan_ulong(x,&uid);
x = env_get("GID"); if (x) scan_ulong(x,&gid); break;
case 'u': scan_ulong(optarg,&uid); break;
case 'g': scan_ulong(optarg,&gid); break;
case '1': flag1 = 1; break;
case 'l': localhost = optarg; break;
#ifdef WITH_SSL
case 's': flagssl = 1; break;
case 'S': flagssl = 0; break;
case 'n': if (!stralloc_copys(&certfile, optarg) ||
!stralloc_0(&certfile) )
strerr_die2x(111,FATAL,"out of memory");
break;
#endif
default: usage();
}
argc -= optind;
argv += optind;
if (!verbosity)
buffer_2->fd = -1;
hostname = *argv++;
if (!hostname) usage();
if (str_equal(hostname,"")) hostname = "0.0.0.0";
if (str_equal(hostname,"0")) hostname = "0.0.0.0";
x = *argv++;
if (!x) usage();
if (!x[scan_ulong(x,&u)])
localport = u;
else {
se = getservbyname(x,"tcp");
if (!se)
strerr_die3x(111,FATAL,"unable to figure out port number for ",x);
localport = ntohs(se->s_port);
}
if (!*argv) usage();
sig_block(sig_child);
sig_catch(sig_child,sigchld);
sig_catch(sig_term,sigterm);
sig_ignore(sig_pipe);
if (!stralloc_copys(&tmp,hostname))
strerr_die2x(111,FATAL,"out of memory");
if (dns_ip4_qualify(&addresses,&fqdn,&tmp) == -1)
strerr_die4sys(111,FATAL,"temporarily unable to figure out IP address for ",hostname,": ");
if (addresses.len < 4)
strerr_die3x(111,FATAL,"no IP address for ",hostname);
byte_copy(localip,4,addresses.s);
#ifdef WITH_SSL
if (flagssl == 1) {
/* setup SSL context (load key and cert into ctx) */
SSL_library_init();
ctx=SSL_CTX_new(SSLv23_server_method());
if (!ctx) strerr_die2x(111,FATAL,"unable to create SSL context");
if(SSL_CTX_use_RSAPrivateKey_file(ctx, certfile.s, SSL_FILETYPE_PEM) != 1)
strerr_die2x(111,FATAL,"unable to load RSA private key");
if(SSL_CTX_use_certificate_file(ctx, certfile.s, SSL_FILETYPE_PEM) != 1)
strerr_die2x(111,FATAL,"unable to load certificate");
}
#endif
s = socket_tcp();
if (s == -1)
strerr_die2sys(111,FATAL,"unable to create socket: ");
if (socket_bind4_reuse(s,localip,localport) == -1)
strerr_die2sys(111,FATAL,"unable to bind: ");
if (socket_local4(s,localip,&localport) == -1)
strerr_die2sys(111,FATAL,"unable to get local address: ");
if (socket_listen(s,backlog) == -1)
strerr_die2sys(111,FATAL,"unable to listen: ");
ndelay_off(s);
if (gid) if (prot_gid(gid) == -1)
strerr_die2sys(111,FATAL,"unable to set gid: ");
if (uid) if (prot_uid(uid) == -1)
strerr_die2sys(111,FATAL,"unable to set uid: ");
localportstr[fmt_ulong(localportstr,localport)] = 0;
if (flag1) {
buffer_init(&b,write,1,bspace,sizeof bspace);
buffer_puts(&b,localportstr);
buffer_puts(&b,"\n");
buffer_flush(&b);
}
close(0);
close(1);
printstatus();
for (;;) {
while (numchildren >= limit) sig_pause();
sig_unblock(sig_child);
t = socket_accept4(s,remoteip,&remoteport);
sig_block(sig_child);
if (t == -1) continue;
++numchildren; printstatus();
switch(fork()) {
case 0:
close(s);
doit(t);
if ((fd_move(0,t) == -1) || (fd_copy(1,0) == -1))
strerr_die2sys(111,DROP,"unable to set up descriptors: ");
sig_uncatch(sig_child);
sig_unblock(sig_child);
sig_uncatch(sig_term);
sig_uncatch(sig_pipe);
#ifdef WITH_SSL
if (flagssl == 1) {
if (pipe(pi2c) != 0)
strerr_die2sys(111,DROP,"unable to create pipe: ");
if (pipe(pi4c) != 0)
strerr_die2sys(111,DROP,"unable to create pipe: ");
switch(fork()) {
case 0:
close(0); close(1);
close(pi2c[1]);
close(pi4c[0]);
if ((fd_move(0,pi2c[0]) == -1) || (fd_move(1,pi4c[1]) == -1))
strerr_die2sys(111,DROP,"unable to set up descriptors: ");
/* signals are allready set in the parent */
pathexec(argv);
strerr_die4sys(111,DROP,"unable to run ",*argv,": ");
case -1:
strerr_die2sys(111,DROP,"unable to fork: ");
default:
ssl = SSL_new(ctx);
if (!ssl)
strerr_die2x(111,DROP,"unable to set up SSL session");
sbio = BIO_new_socket(0,BIO_NOCLOSE);
if (!sbio)
strerr_die2x(111,DROP,"unable to set up BIO socket");
SSL_set_bio(ssl,sbio,sbio);
close(pi2c[0]);
close(pi4c[1]);
translate(ssl, pi2c[1], pi4c[0], 3600);
_exit(0);
}
}
#endif
pathexec(argv);
strerr_die4sys(111,DROP,"unable to run ",*argv,": ");
case -1:
strerr_warn2(DROP,"unable to fork: ",&strerr_sys);
--numchildren; printstatus();
}
close(t);
}
}
#ifdef WITH_SSL
static int allwrite(int fd, char *buf, int len)
{
int w;
while (len) {
w = write(fd,buf,len);
if (w == -1) {
if (errno == error_intr) continue;
return -1; /* note that some data may have been written */
}
if (w == 0) ; /* luser's fault */
buf += w;
len -= w;
}
return 0;
}
static int allwritessl(SSL* ssl, char *buf, int len)
{
int w;
while (len) {
w = SSL_write(ssl,buf,len);
if (w == -1) {
if (errno == error_intr) continue;
return -1; /* note that some data may have been written */
}
if (w == 0) ; /* luser's fault */
buf += w;
len -= w;
}
return 0;
}
char tbuf[2048];
void translate(SSL* ssl, int clearout, int clearin, unsigned int iotimeout)
{
struct taia now;
struct taia deadline;
iopause_fd iop[2];
int flagexitasap;
int iopl;
int sslout, sslin;
int n, r;
sslin = SSL_get_fd(ssl);
sslout = SSL_get_fd(ssl);
if (sslin == -1 || sslout == -1)
strerr_die2x(111,DROP,"unable to set up SSL connection");
flagexitasap = 0;
if (SSL_accept(ssl)<=0)
strerr_die2x(111,DROP,"unable to accept SSL connection");
while (!flagexitasap) {
taia_now(&now);
taia_uint(&deadline,iotimeout);
taia_add(&deadline,&now,&deadline);
/* fill iopause struct */
iopl = 2;
iop[0].fd = sslin;
iop[0].events = IOPAUSE_READ;
iop[1].fd = clearin;
iop[1].events = IOPAUSE_READ;
/* do iopause read */
iopause(iop,iopl,&deadline,&now);
if (iop[0].revents) {
/* data on sslin */
n = SSL_read(ssl, tbuf, sizeof(tbuf));
if ( n < 0 )
strerr_die2sys(111,DROP,"unable to read form network: ");
if ( n == 0 )
flagexitasap = 1;
r = allwrite(clearout, tbuf, n);
if ( r < 0 )
strerr_die2sys(111,DROP,"unable to write to client: ");
}
if (iop[1].revents) {
/* data on clearin */
n = read(clearin, tbuf, sizeof(tbuf));
if ( n < 0 )
strerr_die2sys(111,DROP,"unable to read form client: ");
if ( n == 0 )
flagexitasap = 1;
r = allwritessl(ssl, tbuf, n);
if ( r < 0 )
strerr_die2sys(111,DROP,"unable to write to network: ");
}
if (!iop[0].revents && !iop[1].revents)
strerr_die2x(0, DROP,"timeout reached without input");
}
}
#endif
next prev parent reply other threads:[~2004-06-06 5:09 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-06-05 15:28 clone() <-> getpid() bug in 2.6? Russell Leighton
2004-06-05 20:45 ` Linus Torvalds
2004-06-05 20:55 ` Arjan van de Ven
2004-06-05 21:13 ` Linus Torvalds
2004-06-05 21:48 ` Robert Love
2004-06-05 22:44 ` Linus Torvalds
2004-06-05 21:53 ` Chris Wedgwood
2004-06-05 22:47 ` Robert Love
2004-06-05 22:57 ` David S. Miller
2004-06-05 23:01 ` Linus Torvalds
2004-06-05 23:07 ` Davide Libenzi
2004-06-05 23:18 ` Linus Torvalds
2004-06-05 23:26 ` Davide Libenzi
2004-06-06 5:08 ` Kalin KOZHUHAROV [this message]
2004-06-06 5:13 ` Chris Wedgwood
2004-06-06 5:34 ` Kalin KOZHUHAROV
2004-06-06 6:07 ` Linus Torvalds
2004-06-06 6:43 ` Kalin KOZHUHAROV
2004-06-06 7:57 ` Erik Andersen
2004-06-06 16:57 ` Linus Torvalds
2004-06-06 18:53 ` Simon Kirby
2004-06-06 19:00 ` Linus Torvalds
2004-06-06 9:52 ` Bernd Eckenfels
2004-06-06 13:07 ` Paul Rolland
2004-06-06 17:20 ` Patrick J. LoPresti
2004-06-06 17:31 ` Paul Rolland
2004-06-06 17:43 ` Davide Libenzi
2004-06-06 18:17 ` Rik van Riel
2004-06-06 18:37 ` Patrick J. LoPresti
2004-06-06 16:33 ` chris
[not found] ` <200406062022.54320.vda@port.imtp.ilyichevsk.odessa.ua>
2004-06-06 17:55 ` Linus Torvalds
2004-06-07 18:20 ` Bruce Guenter
2004-06-08 11:06 ` Kalin KOZHUHAROV
2004-06-05 23:19 ` Robert Love
2004-06-06 14:29 ` Russell Leighton
2004-06-06 15:38 ` Using getpid() often, another way? [was Re: clone() <-> getpid() bug in 2.6?] Russell Leighton
2004-06-06 15:44 ` Robert Love
2004-06-07 0:20 ` Russell Leighton
2004-06-06 15:58 ` Arjan van de Ven
2004-06-06 23:49 ` Russell Leighton
2004-06-07 12:13 ` Arjan van de Ven
2004-06-07 13:48 ` Sean Neakums
2004-06-07 14:00 ` Christoph Hellwig
2004-06-07 14:10 ` Sean Neakums
2004-06-07 18:42 ` David Mosberger
2004-06-07 23:02 ` Russell Leighton
2004-06-07 23:27 ` David Mosberger
2004-06-08 6:01 ` Arjan van de Ven
2004-06-08 9:48 ` Eric W. Biederman
2004-06-07 0:09 ` Russell Leighton
2004-06-07 12:20 ` Arjan van de Ven
2004-06-06 17:19 ` Linus Torvalds
2004-06-12 9:15 ` Dominik Straßer
2004-06-12 13:47 ` Linus Torvalds
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=40C2A6E4.7020103@ThinRope.net \
--to=kalin@thinrope.net \
--cc=arjanv@redhat.com \
--cc=cw@f00f.org \
--cc=davidel@xmailserver.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rml@ximian.com \
--cc=russ@elegant-software.com \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.