LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Fedora
User Name
Password
Fedora This forum is for the discussion of the Fedora Project.

Notices


Reply
  Search this Thread
Old 01-03-2016, 10:50 AM   #1
jasonmelbye
LQ Newbie
 
Registered: Apr 2015
Posts: 16

Rep: Reputation: Disabled
Shared Library Search and Cache


Hello,

I'm posting this in the Fedora forum because that is the specific distribution I'm running, although I believe this is a fairly generic question.

I'm trying to better understand how shared libraries are searched for. I have a library I am trying to work with that is looking for "libmysqlclient_r.so".

I ran
Code:
$ dnf provides */libmysqlclient_r.so
and installed mariadb-devel.

After installing that, I have a new ld config file:
/etc/ld.so.conf.d/mariadb-x86_64.conf

With the contents
Code:
/usr/lib64/mysql
That directory looks like:
Code:
$ ls -l /usr/lib64/mysql/
total 3504
lrwxrwxrwx. 1 root root      17 Aug 12 04:36 libmysqlclient_r.so -> libmysqlclient.so
lrwxrwxrwx. 1 root root      20 Aug 12 04:36 libmysqlclient.so -> libmysqlclient.so.18
lrwxrwxrwx. 1 root root      24 Aug 12 04:36 libmysqlclient.so.18 -> libmysqlclient.so.18.0.0
-rwxr-xr-x. 1 root root 3582848 Aug 12 04:39 libmysqlclient.so.18.0.0
drwxr-xr-x. 2 root root    4096 Aug 28 07:12 plugin
However, the library I am trying to work with is still unable to find libmysqlclient_r.so.

I ran ldconfig and tried again with no change in the outcome.

What is interesting is that if I look at the cache, that particular shared library is not listed:
Code:
$ ldconfig -p | grep libmysqlclient
	libmysqlclient.so.18 (libc6,x86-64) => /usr/lib64/mysql/libmysqlclient.so.18
	libmysqlclient.so (libc6,x86-64) => /usr/lib64/mysql/libmysqlclient.so
Here's where my understanding of the shared library system ends. I was expecting that libmysqlclient_r.so would also be shown in those results. Why would libmysqlclient.so be present, but not libmysqlclient_r.so (which is just a symlink to libmysqlclient_r.so?

How can I make it so that libmysqlclient_r.so is found when the system searches the shared libraries?

A couple other notes:
- I'm running Fedora 22 (x86_64)
- The library I'm working with is a Common Lisp library, cl-mysql, which is attempting to load "libmysqlclient_r.so" via the c foreign function interface
- If I change cl-mysql to look for just "libmysqlclient.so" instead, it works, however, I would still like to better understand what is going on here.

Any help is greatly appreciated,

Jason

Last edited by jasonmelbye; 01-03-2016 at 10:51 AM.
 
Old 01-04-2016, 05:36 AM   #2
business_kid
LQ Guru
 
Registered: Jan 2006
Location: Ireland
Distribution: Slackware, Slarm64 & Android
Posts: 16,139

Rep: Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307
Generally libraries were in /lib, &/usr/lib. Now it's more likiely to be /lib64 & &/usr/lib64. If you drop s symlink to your lib in there, it will be found.

/etc/ld.so.conf usually tells the system where, and in what order to search for libs in other strange places. I see fedora used /etc/ld.so.conf.d/, so they apparently made a directory to dump lib assignments in. Useful when adding & deleting packages, which goes ona lot in fedora.
 
Old 01-04-2016, 08:12 PM   #3
jasonmelbye
LQ Newbie
 
Registered: Apr 2015
Posts: 16

Original Poster
Rep: Reputation: Disabled
Thank you, that does resolve the problem and I believe I understand why. However, I still don't understand why the links in /usr/lib64/mysql did not work.

From man ld.so:
Quote:
If a library dependency does not contain a slash, then it is searched
for in the following order:

...

o From the cache file /etc/ld.so.cache, which contains a compiled list
of candidate libraries previously found in the augmented library
path. If, however, the binary was linked with the -z nodeflib
linker option, libraries in the default library paths are skipped.
Libraries installed in hardware capability directories (see below)
are preferred to other libraries.

o In the default path /lib, and then /usr/lib. If the binary was
linked with the -z nodeflib linker option, this step is skipped.
I'm assuming that if you reach the last search item, /usr/lib64 is also searched and therefore, putting a link there works.

However, I was expecting it to work without creating a link in /usr/lib64 because of the prior search item, the cache file.

I assume that if I don't see the library in the output of
Code:
$ ldconfig -p
then it is not in the cache. Why is this particular library not being cached?

Again, my setup is as follows
/etc/ld.so.conf
Code:
include ld.so.conf.d/*.conf
/etc/ld.so.conf.d/mariadb-x86_64.conf
Code:
/usr/lib64/mysql
Code:
$ ls -l /etc/lib64/mysql
total 3504
lrwxrwxrwx. 1 root root      17 Aug 12 04:36 libmysqlclient_r.so -> libmysqlclient.so
lrwxrwxrwx. 1 root root      20 Aug 12 04:36 libmysqlclient.so -> libmysqlclient.so.18
lrwxrwxrwx. 1 root root      24 Aug 12 04:36 libmysqlclient.so.18 -> libmysqlclient.so.18.0.0
-rwxr-xr-x. 1 root root 3582848 Aug 12 04:39 libmysqlclient.so.18.0.0
drwxr-xr-x. 2 root root    4096 Aug 28 07:12 plugin
Code:
$ ldconfig -p | grep mysql
	libmysqlclient.so.18 (libc6,x86-64) => /usr/lib64/mysql/libmysqlclient.so.18
	libmysqlclient.so.18 (libc6,x86-64) => /lib64/libmysqlclient.so.18
	libmysqlclient.so (libc6,x86-64) => /usr/lib64/mysql/libmysqlclient.so
My expectation is that the ld.so.conf (and included) files should have been sufficient. Any thoughts about why it is not?
 
Old 01-04-2016, 11:46 PM   #4
berndbausch
LQ Addict
 
Registered: Nov 2013
Location: Tokyo
Distribution: Mostly Ubuntu and Centos
Posts: 6,316

Rep: Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002
Run ldconfig without the -p option to update the cache. You can add -v to see what it does.
 
Old 01-05-2016, 07:52 AM   #5
jasonmelbye
LQ Newbie
 
Registered: Apr 2015
Posts: 16

Original Poster
Rep: Reputation: Disabled
I have been running ldconfig prior to printing out the contents of the cache.

Code:
$ sudo ldconfig -v | grep mysql
ldconfig: Can't stat /libx32: No such file or directory
ldconfig: Path `/usr/lib' given more than once
ldconfig: Path `/usr/lib64' given more than once
ldconfig: Can't stat /usr/libx32: No such file or directory
/usr/lib64/mysql:
	libmysqlclient.so.18 -> libmysqlclient_r.so
Code:
$ ldconfig -p | grep mysql
	libmysqlclient.so.18 (libc6,x86-64) => /usr/lib64/mysql/libmysqlclient.so.18
	libmysqlclient.so (libc6,x86-64) => /usr/lib64/mysql/libmysqlclient.so
From the verbose output, you can see that the /usr/lib64/mysql directory is being processed. However, the file /usr/lib64/mysql/libmysqlclient_r.so is not being added to the cache.
 
Old 01-05-2016, 08:02 AM   #6
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,685

Rep: Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274
probably this link is incorrect: libmysqlclient.so.18 -> libmysqlclient_r.so
you need to link libmysqlclient_r.so -> libmysqlclient.so.18
 
Old 01-05-2016, 07:13 PM   #7
jasonmelbye
LQ Newbie
 
Registered: Apr 2015
Posts: 16

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by pan64 View Post
probably this link is incorrect: libmysqlclient.so.18 -> libmysqlclient_r.so
you need to link libmysqlclient_r.so -> libmysqlclient.so.18
I did not create that link, and in fact there is no such link on my system. I have to admit I'm not sure how to read the output of ldconfig -v. As far as the file system goes, the links look like I posted previously:

Code:
$ ls -l /usr/lib64/mysql
total 3504
lrwxrwxrwx. 1 root root      17 Aug 12 04:36 libmysqlclient_r.so -> libmysqlclient.so
lrwxrwxrwx. 1 root root      20 Aug 12 04:36 libmysqlclient.so -> libmysqlclient.so.18
lrwxrwxrwx. 1 root root      24 Aug 12 04:36 libmysqlclient.so.18 -> libmysqlclient.so.18.0.0
-rwxr-xr-x. 1 root root 3582848 Aug 12 04:39 libmysqlclient.so.18.0.0
drwxr-xr-x. 2 root root    4096 Aug 28 07:12 plugin
 
Old 01-06-2016, 01:05 AM   #8
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,685

Rep: Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274
return back to the original question: how did you try it, what was the original error?
you may try strace to check what's happening and also set LD_LIBRARY_PATH
 
Old 01-06-2016, 08:01 AM   #9
jasonmelbye
LQ Newbie
 
Registered: Apr 2015
Posts: 16

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by pan64 View Post
return back to the original question: how did you try it, what was the original error?
you may try strace to check what's happening and also set LD_LIBRARY_PATH
The original problem is as stated above. I installed mariadb-devel, ran ldconfig for good measure, and the library I am working with (cl-mysql) was unable to find libmysqlclient_r.so.

I believe this is because ldconfig is not putting it into the shared library cache (it is not listed in ldconfig -p). I would like for this to work using ldconfig.

Alternatives are:
a.) Create a link in /usr/lib64
This works. I believe it works because it bypasses ldconfig all together. ld.so looks in /usr/lib64 as a last resort (man page quoted above). However, I don't like this as a solution because it brings me no further in understanding what is happening with ldconfig and because 6 months and a couple upgrades later when something isn't working, I am likely not going to remember to check on this link.

b.) I haven't done so, but suspect setting LD_LIBRARY_PATH as you suggest would also work. But again, this is going around ldconfig.

c.) I can also modify cl-mysql to link against libmysqlclient.so (instead of _r.so). This works, however I don't maintain cl-mysql and it could be in use on systems where there is a meaningful difference between libmysqlclient.so and libmysqlclient_r.so (the _r.so version is guaranteed to be reentrant). However, this is still an interesting result. libmysqlclient.so is being stored in the shared library cache. Why is libmysqlclient_r.so not?

To be very specific, I would like to understand what is happening when I run ldconfig and build the cache. If libmysqlclient_r.so is not being cached by ldconfig, I would like to understand why.
 
Old 01-06-2016, 08:14 AM   #10
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,685

Rep: Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274
http://tldp.org/HOWTO/Program-Librar...libraries.html
http://www.yolinux.com/TUTORIALS/Lib...ndDynamic.html
 
Old 01-07-2016, 06:29 AM   #11
business_kid
LQ Guru
 
Registered: Jan 2006
Location: Ireland
Distribution: Slackware, Slarm64 & Android
Posts: 16,139

Rep: Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307
Yet another option is to add your path containing libmysqlclient_r.so to /etc/ld.so.conf, THRN run ldconfig
 
Old 01-07-2016, 09:19 PM   #12
jasonmelbye
LQ Newbie
 
Registered: Apr 2015
Posts: 16

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by business_kid View Post
Yet another option is to add your path containing libmysqlclient_r.so to /etc/ld.so.conf, THRN run ldconfig
My config already includes the path by including the /etc/ld.so.conf.d/*.conf files (I've listed the setup above).

Stil, to be sure, I modified my /etc/ld.so.conf file to look as follows
Code:
/usr/lib64/mysql
include ld.so.conf.d/*.conf
Code:
$ sudo ldconfig -v | grep mysql
ldconfig: Path `/usr/lib64/mysql' given more than once
ldconfig: Can't stat /libx32: No such file or directory
ldconfig: Path `/usr/lib' given more than once
ldconfig: Path `/usr/lib64' given more than once
ldconfig: Can't stat /usr/libx32: No such file or directory
/usr/lib64/mysql:
	libmysqlclient.so.18 -> libmysqlclient_r.so

$ ldconfig -p | grep mysql
	libmysqlclient.so.18 (libc6,x86-64) => /usr/lib64/mysql/libmysqlclient.so.18
	libmysqlclient.so (libc6,x86-64) => /usr/lib64/mysql/libmysqlclient.so
The library I am working with is still unable to find libmysqlclient_r.so with this configuration.

I grabed the glibc source to try to understand what ldconfig is doing, but there is too much preprocessor magic for me to tackle right now.
 
Old 01-08-2016, 05:44 AM   #13
business_kid
LQ Guru
 
Registered: Jan 2006
Location: Ireland
Distribution: Slackware, Slarm64 & Android
Posts: 16,139

Rep: Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307Reputation: 2307
One last possibility.

64 bit libs & 32 bit libs are incompatible. Run file on the lib, and the executble using it and check they are both 32 or 64 bit.
 
Old 01-09-2016, 10:46 AM   #14
jasonmelbye
LQ Newbie
 
Registered: Apr 2015
Posts: 16

Original Poster
Rep: Reputation: Disabled
Arrow

Everything is 64-bit. The library I am working with is a common lisp library, so below I simply run file on the common lisp runtime, /usr/bin/sbcl.

Code:
$ file /usr/lib64/mysql/libmysqlclient_r.so 
/usr/lib64/mysql/libmysqlclient_r.so: symbolic link to `libmysqlclient.so'
$ file /usr/lib64/mysql/libmysqlclient.so
/usr/lib64/mysql/libmysqlclient.so: symbolic link to `libmysqlclient.so.18'
$ file /usr/lib64/mysql/libmysqlclient.so.18
/usr/lib64/mysql/libmysqlclient.so.18: symbolic link to `libmysqlclient.so.18.0.0'
$ file /usr/lib64/mysql/libmysqlclient.so.18.0.0 
/usr/lib64/mysql/libmysqlclient.so.18.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=92c4646a1af3eba06a4c9d569ada7b06d3bcb61e, stripped
$ file /usr/bin/sbcl
/usr/bin/sbcl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=a5042a2bd1709bb6c634a99dc710badb4b27b247, stripped
The common lisp runtime interacts with c libraries via dlopen and family.

To simplify the problem, I wrote a simple program that links against the mysql client library and calls my_init()
https://dev.mysql.com/doc/refman/5.7/en/my-init.html

Code:
#include <stdio.h>
#include <my_global.h>
#include <my_sys.h>

int main(int argc, char** argv)
{
  my_init();
  printf("Done\n");

  return 0;
}
Code:
$ gcc -L/usr/lib64/mysql -lmysqlclient_r -I/usr/include/mysql -o mysql_test_init mysql_test_init.c 
$ ./mysql_test_init
Done
$ ldd mysql_test_init
	linux-vdso.so.1 (0x00007ffffc166000)
	libmysqlclient.so.18 => /usr/lib64/mysql/libmysqlclient.so.18 (0x00007f0de4d3f000)
	libc.so.6 => /lib64/libc.so.6 (0x0000003f5c400000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003f5cc00000)
	libz.so.1 => /lib64/libz.so.1 (0x0000003f5d400000)
	libssl.so.10 => /lib64/libssl.so.10 (0x0000003520800000)
	libcrypto.so.10 => /lib64/libcrypto.so.10 (0x0000003f5bc00000)
	libdl.so.2 => /lib64/libdl.so.2 (0x0000003f5d000000)
	libstdc++.so.6 => /lib64/libstdc++.so.6 (0x0000003f5b800000)
	libm.so.6 => /lib64/libm.so.6 (0x0000003f5c800000)
	/lib64/ld-linux-x86-64.so.2 (0x000055a274862000)
	libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x000000351fc00000)
	libkrb5.so.3 => /lib64/libkrb5.so.3 (0x0000003520400000)
	libcom_err.so.2 => /lib64/libcom_err.so.2 (0x0000003f66800000)
	libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x000000351f800000)
	libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003f5b400000)
	libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x0000003520000000)
	libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x0000003f68000000)
	libresolv.so.2 => /lib64/libresolv.so.2 (0x0000003f60c00000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x000000351da00000)
	libpcre.so.1 => /lib64/libpcre.so.1 (0x000000351d600000)
I was half-expecting that not to work - it wouldn't find the mysql library at runtime. But as you can see in the ldd output, it was resolved fine.

So, to take it to the next step, I tried to write a simple program using dlopen.

Code:
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char** argv)
{
  char* library_name = argv[1];
  printf("passed in library name: %s\n", library_name);

  void* handle = dlopen(library_name, RTLD_LAZY);

  if (handle == NULL) {
    printf("failed to dlopen\n");
    exit(0);
  }
}
Here I think I can begin to reproduce the problem. dlopen can find libmysqlclient.so, but it cannot find libmysqlclient_r.so.

Code:
$ gcc -ldl -o mysql_test_dlopen mysql_test.c
$ ./mysql_test_dlopen libm.so # math library
passed in library name: libm.so
$ ./mysql_test_dlopen libmysqlclient.so
passed in library name: libmysqlclient.so
$ ./mysql_test_dlopen libmysqlclient_r.so # the one I want!
passed in library name: libmysqlclient_r.so
failed to dlopen
I'm still trying to determine if this is in part a problem with ldconfig or not. Shouldn't I expect to see libmysqlclient_r.so in the ldconfig cache? If not, why not?
 
Old 01-10-2016, 04:22 AM   #15
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,685

Rep: Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274Reputation: 7274
can you please add -pthread to gcc to compile and link things. Probably that will make sense. And also you can try to strace the last two commands you executed to see what is the difference.
 
  


Reply

Tags
ldconfig


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
When to rebuild the systems shared library cache fakie_flip Linux - Software 4 10-21-2012 04:20 AM
gcc link shared library against another shared library qcp Linux - Newbie 1 07-25-2008 11:15 AM
RedHat Dynamic loader shared library search order is backward rjbdevr Red Hat 0 03-26-2008 04:39 PM
howto compile bin with my library using all-static and shared linked standart library stpg Programming 4 06-29-2004 04:20 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Fedora

All times are GMT -5. The time now is 05:40 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration