java + procfs + nullfs = disaster

b. f. bf1783 at googlemail.com
Mon Aug 15 22:57:47 UTC 2011


On 8/12/11, Greg Lewis <glewis at eyesbeyond.com> wrote:
> On Fri, Aug 12, 2011 at 02:37:04PM +0300, Kostik Belousov wrote:
>> On Thu, Aug 11, 2011 at 03:18:38PM -0400, b. f. wrote:
>> > I've run into a problem building java ports on my FreeBSD 9 amd64
>> > tinderbox.  Following an earlier suggestion,
>> >
>> > http://www.marcuscom.com/pipermail/tinderbox-list/2010-September/001957.html
>> >
>> > I've been performing builds in a tmpfs that is nullfs-mounted on a ufs
>> > mountpoint.  After building packages for java/diablo-jdk16 on
>> > {7.3,8.1}-{i386,amd64}, the ports that depend upon it fail when
>> > invoking java binary executables from that port, with:
>> >
>> > Error: could not find libjava.so
>> > Error: could not find Java 2 Runtime Environment.
>> >
>> > A search of the mailing lists reveals that this problem has occurred
>> > for the past several years, and has sometimes been attributed to the
>> > fact that a procfs is mounted on /proc, and sometimes to vague nullfs
>> > problems, but has never been solved:
>> >
>> > http://lists.freebsd.org/pipermail/freebsd-java/2011-March/009169.html
>> > http://lists.freebsd.org/pipermail/freebsd-stable/2010-May/056814.html
>> > http://lists.freebsd.org/pipermail/freebsd-java/2009-May/008104.html
>> > http://lists.freebsd.org/pipermail/freebsd-java/2009-February/007854.html
>> > http://lists.freebsd.org/pipermail/freebsd-stable/2005-February/011629.html
>> > ...
>> >
>> > However, it seems rather to be a combination of factors, because, for
>> > example, if I:
>> >
>> > mount /proc
>> > mkdir /tmp/java
>> > tar -C /tmp/java -xvf
>> > /home/shared/freebsd/tinderbox/packages/8.1-amd64-u1/All/diablo-jdk-1.6.0.07.02_15.tbz
>> > cd /tmp/diablo-jdk1.6.0/bin
>> > truss ./java -version
>> >
>> > , I obtain:
>> >
>> > ...
>> >
>> > readlink("/proc/curproc/file","/tmp/java/diablo-jdk1.6.0/bin/java",1024)
>> > = 35 (0x23)
>> > access("/tmp/java/diablo-jdk1.6.0/lib/amd64/libjava.so",0) ERR#2 'No
>> > such file or directory'
>> > access("/tmp/java/diablo-jdk1.6.0/jre/lib/amd64/libjava.so",0) = 0 (0x0)
>> >
>> > ...
>> >
>> > , and libjava.so is found.  Then, if I:
>> >
>> >  umount /proc
>> > truss ./java -version
>> >
>> > , the library is also found, in a slightly different manner:
>> >
>> > +readlink("/proc/curproc/file",0x7fffffffca40,1024) ERR#2 'No such
>> > file or directory'
>> > +__getcwd("/tmp/java/diablo-jdk1.6.0/bin",1026)   = 0 (0x0)
>> > +stat("/tmp/java/diablo-jdk1.6.0/bin/./java",{ mode=-rwxr-xr-x
>> > ,inode=3121,size=95014,blksize=4096 }) = 0 (0x0)
>> > +lstat("/tmp",{ mode=drwxrwxrwt ,inode=2,size=600,blksize=4096 }) = 0
>> > (0x0)
>> > +lstat("/tmp/java",{ mode=drwxr-xr-x ,inode=15,size=280,blksize=4096
>> > }) = 0 (0x0)
>> > +lstat("/tmp/java/diablo-jdk1.6.0",{ mode=drwxr-xr-x
>> > ,inode=3105,size=560,blksize=4096 }) = 0 (0x0)
>> > +lstat("/tmp/java/diablo-jdk1.6.0/bin",{ mode=drwxr-xr-x
>> > ,inode=3112,size=1720,blksize=4096 }) = 0 (0x0)
>> > +lstat("/tmp/java/diablo-jdk1.6.0/bin/java",{ mode=-rwxr-xr-x
>> > ,inode=3121,size=95014,blksize=4096 }) = 0 (0x0)
>> >  access("/tmp/java/diablo-jdk1.6.0/lib/amd64/libjava.so",0) ERR#2 'No
>> > such file or directory'
>> >  access("/tmp/java/diablo-jdk1.6.0/jre/lib/amd64/libjava.so",0) = 0
>> > (0x0)
>> >
>> >
>> > However, if I:
>> >
>> > rm -vr /tmp/java
>> > mount /proc
>> > mkdir /tmp/java /root/java
>> > mount -t nullfs /tmp/java /root/java
>> > tar -C /root/java -xvf
>> > /home/shared/freebsd/tinderbox/packages/8.1-amd64-u1/All/diablo-jdk-1.6.0.07.02_15.tbz
>> > cd /root/diablo-jdk1.6.0/bin
>> > truss ./java -version
>> >
>> > then the library cannot be found:
>> >
>> > readlink("/proc/curproc/file","unknown",1024)    = 7 (0x7)
>> > Error: could not find libjava.so
>> > write(2,"Error: could not find libjava.so"...,33) = 33 (0x21)
>> > Error: could not find Java 2 Runtime Environment.
>> > write(2,"Error: could not find Java 2 Run"...,50) = 50 (0x32)
>> This is a long-standing strangeness in our procfs. I wonder how much
>> will break after the following. Can you try ls -l /proc/<pid>/
>> in the situation when file previously shown 'unknown' ?
>>
>> diff --git a/sys/fs/procfs/procfs.c b/sys/fs/procfs/procfs.c
>> index 8b69eb1..514e279 100644
>> --- a/sys/fs/procfs/procfs.c
>> +++ b/sys/fs/procfs/procfs.c
>> @@ -67,20 +67,23 @@
>>  int
>>  procfs_doprocfile(PFS_FILL_ARGS)
>>  {
>> -	char *fullpath = "unknown";
>> -	char *freepath = NULL;
>> +	char *fullpath;
>> +	char *freepath;
>>  	struct vnode *textvp;
>> +	int error;
>>
>> +	freepath = NULL;
>>  	PROC_LOCK(p);
>>  	textvp = p->p_textvp;
>>  	vhold(textvp);
>>  	PROC_UNLOCK(p);
>> -	vn_fullpath(td, textvp, &fullpath, &freepath);
>> +	error = vn_fullpath(td, textvp, &fullpath, &freepath);
>>  	vdrop(textvp);
>> -	sbuf_printf(sb, "%s", fullpath);
>> -	if (freepath)
>> +	if (error == 0)
>> +		sbuf_printf(sb, "%s", fullpath);
>> +	if (freepath != NULL)
>>  		free(freepath, M_TEMP);
>> -	return (0);
>> +	return (error);
>>  }
>>
>>  /*

Thank you, Kostik.  After applying this patch, the java binary is able
to locate its libraries in all of the cases above.  Also, my tinderbox
is able to build default java packages.  The output of a ls -l
/proc/... for a process involving a nullfs-mounted java is something
like:

# pgrep java
86219
# ls -l /proc/`pgrep java`
total 0
-r--r--r--  1 root  wheel  0 Aug 15 18:26 cmdline
--w-------  1 root  wheel  0 Aug 15 18:26 ctl
-rw-------  1 root  wheel  0 Aug 15 18:26 dbregs
-r--r--r--  1 root  wheel  0 Aug 15 18:26 etype

ls: /proc/86219/file: No such file or directory
lr--r--r--  1 root  wheel  0 Aug 15 18:26 file
-rw-------  1 root  wheel  0 Aug 15 18:26 fpregs
-r--r--r--  1 root  wheel  0 Aug 15 18:26 map
-rw-------  1 root  wheel  0 Aug 15 18:26 mem
--w-------  1 root  wheel  0 Aug 15 18:26 note
--w-------  1 root  wheel  0 Aug 15 18:26 notepg
-rw-------  1 root  wheel  0 Aug 15 18:26 osrel
-rw-------  1 root  wheel  0 Aug 15 18:26 regs
-r--r--r--  1 root  wheel  0 Aug 15 18:26 rlimit
-r--r--r--  1 root  wheel  0 Aug 15 18:26 status

Can we add these or equivalent changes to procfs for 9.0?  Or would
these changes violate some "unknown" convention?

>
> The other option here is to change the order in which the JDK detects where
> it is and not try /proc as the first option.  Unfortunately that won't
> happen for Diablo since there is unlikely to be another release of that.
> It can be changed for the build from source JDK ports though.

I think that anything that can be done to make the detection process
more robust would be appreciated, as it will be some time, if ever,
before all supported versions of FreeBSD will have compatible procfs
behavior.  If Diablo remains unchanged, it will continue to cause
problems, as it is the default bootstrap compiler.

b.


More information about the freebsd-java mailing list