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!

migrated from serverfault.com Nov 5 '14 at 23:10

This question came from our site for system and network administrators.

  • Interesting question, You could try asking this on an openjdk forum. – Faheem Mitha Nov 6 '14 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 Feb 6 '15 at 17:53
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
    Thanks. Your pointing at /proc/self/exe was the missing clue at my side. Mounting /proc in my chroot did the trick. – Tino Dec 4 '15 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.

  • 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 Oct 30 '14 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. – Andrew Schulman Oct 30 '14 at 17:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.