java + procfs + nullfs = disaster

Greg Lewis glewis at eyesbeyond.com
Fri Aug 12 15:15:07 UTC 2011


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);
>  }
>  
>  /*

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.

-- 
Greg Lewis                          Email   : glewis at eyesbeyond.com
Eyes Beyond                         Web     : http://www.eyesbeyond.com
Information Technology              FreeBSD : glewis at FreeBSD.org


More information about the freebsd-java mailing list