8

I am scripting the creation of chroot jails and part of that automation includes copying various executables and their dependencies into the jail. I am using the following bash line to parse the file paths out of a list of dependencies (for java, for instance):

$ ldd `which java` | grep -o '/[^()]*'
/lib/x86_64-linux-gnu/libz.so.1
/lib/x86_64-linux-gnu/libpthread.so.0
/lib/x86_64-linux-gnu/libdl.so.2
/lib/x86_64-linux-gnu/libc.so.6
/lib64/ld-linux-x86-64.so.2

This works great for Node.js and Python, but when I try to execute java from within the jail, I get an error:

java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory

It turns out that the libjli.so path is missing from the list of dependencies... at least those that ldd shows us (line 5):

$ ldd `which java`
linux-vdso.so.1 =>  (0x00007ffff7f4d000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f7ac3928000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f7ac370c000)
libjli.so => not found
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f7ac3507000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7ac317c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7ac3b48000)

I found the file...

$ find /usr/lib -name libjli.so
/usr/lib/jvm/java-6-openjdk-amd64/lib/amd64/jli/libjli.so
/usr/lib/jvm/java-6-openjdk-amd64/jre/lib/amd64/jli/libjli.so

... but I would like to know why it wasn't listed with ldd. It is a known dependency apparently, but the path is unknown? Any help is appreciated!

2
  • Interesting question, You could try asking this on an openjdk forum. Commented Nov 6, 2014 at 1:38
  • In case someone stumbles on this from google: it seems like it may be a duplicate with unix.stackexchange.com/questions/16656, which has more information (and different answers).
    – yshavit
    Commented Feb 6, 2015 at 17:53

2 Answers 2

7

It's supposed to work out of the box - with no messing with /etc/ld.so.conf* or ldconfig - and it can easily do so. Just mount /proc in your chroot. I do this with the following line in /etc/fstab in my real-root fs:

/proc /var/chroot/ia32/proc none bind

Thus binding it to the real /proc.

Per https://github.com/cedric-vincent/PRoot/issues/9, ld-linux.so (I guess it is) determines $ORIGIN for substituting into the objdump -p's RPATH entries by looking at /proc/self/exe.

How many times have I been bitten by this and had to rediscover it? Please, oh mighty and wise Google, lead me back here expeditiously next time, so future-me can learn again at the knee of past-me!

1
  • 1
    Thanks. Your pointing at /proc/self/exe was the missing clue at my side. Mounting /proc in my chroot did the trick.
    – Tino
    Commented Dec 4, 2015 at 15:05
3

It seems that you need to add

/usr/lib/jvm/java-6-openjdk-amd64/jre/lib/amd64/jli

to /etc/ld.so.conf, or more likely to a new file in /etc/ld.so.conf.d. Then run ldconfig to update the cache so ldd will find the library.

For scripting chroots, you'll probably have less pain in the long run to take a package-based approach, creating a base install first (using e.g. debootstrap on Debian-based hosts), then installing the packages you want. That lets the package manager take care of all of the work of resolving dependencies, installing all of the needed files, and running postinstall tasks.

2
  • And can you tell me why it wasn't in ld.so.conf or one of the included files? Should the OS have put it there during install?
    – Rip Leeb
    Commented Oct 30, 2014 at 16:23
  • No, I don't know that. I can say that I see the same result on my Ubuntu 14.04 host, and yet java starts fine. So it must be resolving the dependency dynamically at run time. Commented Oct 30, 2014 at 17:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .