Package: fakeroot Version: 1.20.2-1 Severity: normal Tags: patch Dear Maintainer,
I'm raising this as requested by Clint in: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=855662#15 Fixing that bug (fakeroot: when msgrcv is interrupted by a signal, faked accidentally reprocesses the previous message) stopped faked from overwriting errno, which led me to realize that my intermittent failure problem while building several packages at once might always be due to EIDRM. (I only had one failure with the patched version from that bug before contriving the patch I submit here, so I don't have a big sample size.) That led me to realize that faked is, by default, inventing a random number on which to base its message queue and semaphore ids. When it then creates the message queues and semaphore, it doesn't check for collisions. Here I present a patch that I hope detects that situation and retries. I haven't seen a failure with this patch, but I've only been running with it since last Friday. I was previously seeing as little as one failure per week. I also haven't attempted the obvious change to fail visibly in this case, which would have given me confidence that the diagnosis was right. I don't know why some of build machines seem more vulnerable than others. I don't know why I've only seen this since they were upgraded to Jessie. I based the patch supplied here on: https://anonscm.debian.org/cgit/users/clint/fakeroot.git/ I wasn't sure whether Clint was asking me to base it instead on some upstream branch. That was at least due to the corporate email link mangler but I'm quite new to git and Debian packaging. This isn't the version I'm running, which is instead based on the Jessie version. I'm open to persuasion for other experiments. -- System Information: Debian Release: 8.7 APT prefers stable-updates APT policy: (990, 'stable-updates'), (990, 'stable'), (500, 'testing-updates'), (500, 'oldstable-updates'), (500, 'oldoldstable'), (500, 'testing'), (500, 'stable'), (500, 'oldstable') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 3.16.0-4-amd64 (SMP w/8 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to en_US.UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages fakeroot depends on: ii libc6 2.19-18+deb8u7 ii libfakeroot 1.20.2-1 fakeroot recommends no packages. fakeroot suggests no packages. -- no debconf information
diff --git a/faked.c b/faked.c index a0f92ca..d280668 100644 --- a/faked.c +++ b/faked.c @@ -1305,6 +1305,7 @@ int main(int argc, char **argv){ #ifndef FAKEROOT_FAKENET union semun sem_union; int justcleanup = 0; + int msgflag = IPC_CREAT|0600; #else /* FAKEROOT_FAKENET */ int sd, val; unsigned int port = 0; @@ -1375,29 +1376,42 @@ int main(int argc, char **argv){ #ifndef FAKEROOT_FAKENET - if(!msg_key) { - srandom(time(NULL)+getpid()*33151); - while(!msg_key && (msg_key!=-1)) /* values 0 and -1 are treated - specially by libfake */ - msg_key=random(); - } + do { + if(!msg_key) { + msgflag |= IPC_EXCL; + srandom(time(NULL)+getpid()*33151); + while(!msg_key && (msg_key!=-1)) /* values 0 and -1 are treated + specially by libfake */ + msg_key=random(); + } - if(debug) - fprintf(stderr,"using %li as msg key\n",(long)msg_key); + if(debug) + fprintf(stderr,"using %li as msg key\n",(long)msg_key); + + msg_get=msgget(msg_key,msgflag); + if (msg_get != -1) + msg_snd=msgget(msg_key+1,msgflag); + if (msg_snd != -1) + sem_id=semget(msg_key+2,1,msgflag); + + if((msg_get==-1)||(msg_snd==-1)||(sem_id==-1)){ + if (errno == EEXIST) { + if(debug) + fprintf(stderr,"using %li as msg key caused a collision, trying again\n",(long)msg_key); + cleanup(-1); + msg_key = 0; + continue; + } + perror("fakeroot, while creating message channels"); + fprintf(stderr, "This may be due to a lack of SYSV IPC support.\n"); + cleanup(-1); + exit(1); + } + } while(msg_key == 0); - msg_get=msgget(msg_key,IPC_CREAT|0600); - msg_snd=msgget(msg_key+1,IPC_CREAT|0600); - sem_id=semget(msg_key+2,1,IPC_CREAT|0600); sem_union.val=1; semctl (sem_id,0,SETVAL,sem_union); - if((msg_get==-1)||(msg_snd==-1)||(sem_id==-1)){ - perror("fakeroot, while creating message channels"); - fprintf(stderr, "This may be due to a lack of SYSV IPC support.\n"); - cleanup(-1); - exit(1); - } - if(debug) fprintf(stderr,"msg_key=%li\n",(long)msg_key);