here is what we are trying to do 1. we have 2, 3rd party DMAPI libraries libdmapi.so(for gpfs) and libdm.so(for xfs) 2. we have a base class (class lowlevel) with virtual interfaces, we have two derived classes which derive from lowlevel.cpp gpfslowlevel.cpp and xfslowlevel.cpp 3. each of the derived classes are packaged into their own .so and each one individually links with the respective 3rd party dmapi library. (There is another layer in between the lowlevel and the 3rd party DMAPI but I have left it out for simplicity here) 4. we create a top level shared object called lowlevel.so which is used by all the apps. so the app will create a lowlevel object depending on which FS we deal with at run time. and then it makes calls on that object. Depending on which object is making the call, it should get routed to the right 3rd party DMAPI library. but what is happening is that all calls are getting routed to the first 3rd party dmapi library that gets loaded, the first one that gets loaded is always the one that appears first in the order of libraries to be linked in the makefile. ***so that question is , is there a way to force symbol resolution to happen to a particular library at link time on linux? (w/o using an explicit dlopen call)*** I got this working on AIX. things gets routed properly to the right library depending on which object is making the calls. I used -qmkshrobj on AIX WITHOUT the -brtl option. -brtl enables run time linking. I am attaching the code on both AIX and Linux. (to make the binaries just execute the Makefile (so its a file with all the commands not a real makefile).) (to run the library run ./main) going through the source and the makefiles may be a little laborious. I thank you for your patience :) and would appreciate any help in the matter. thanks Sudha begin DMAPI.cpp =========== #include <stdio.h> #include <stdlib.h> #include <errno.h> /* Include FS specifc dmapi jheader files */ #include "DMAPI.h" #ifdef XFSDMAPI //xfs dmapi.h in linux src code path ///usr///src/linux-2.6.5-7.244/fs/dmapi/dmapi.h #include <dmapi.h> #endif #ifdef GPFSDMAPI //in /usr/include/dmapi.h on both linux + aix #include <dmapi.h> #endif #ifdef JFSDMAPI #include <sys/dmapi.h> #endif extern int errno; char* FS_DMAPI::init_dmapi(void) { const char * func="DMAPI::init"; #ifdef JFSDMAPI logfile="/tmp/jfsdmapi.log"; #endif #ifdef XFSDMAPI logfile="/tmp/xfsdmapi.log"; #endif #ifdef GPFSDMAPI logfile="/tmp/gpfsdmapi.log"; #endif fprintf(stdout, "opening logfile %s for writing\n", logfile); if ((logfp = fopen(logfile, "a")) == NULL) { printf("Unable to open logfile %s for writing\n", logfile); exit(-1); } if (dmapi_ver==0 && dm_init_service(&dmapi_ver)<0) { fprintf(logfp, "Failed to initialize DMAPI service: %s\n", strerror(errno)); exit(-1); } fprintf(stdout, "Initialized DMAPI service successfully: %s\n", dmapi_ver); fprintf(logfp, "Initialized DMAPI service successfully: %s\n", dmapi_ver); fflush(logfp); return dmapi_ver; } void FS_DMAPI::print_objtype(void) { #ifdef GPFSDMAPI fprintf(logfp, "GPFS\n"); printf("GPFS\n"); #elif XFSDMAPI printf("XFS\n"); #elif JFSDMAPI fprintf(logfp, "JFS\n"); printf("JFS\n"); #endif char *a = new char; } ======================================= end DMAPI.cpp begin DMAPI.h =========== #ifndef DMAPI_H #define DMAPI_H #include <stdio.h> #include <string.h> namespace FS_DMAPI { char* init_dmapi(void); void print_objtype(void); static char *dmapi_ver; static char *logfile; static FILE *logfp; }; #endif /* DMAPI_H */ ======================================= end DMAPI.h begin fs_lowlevel.cpp =========== #include <stdio.h> #include "lowlevel.h" #include "jfs_lowlevel.h" #include "gpfs_lowlevel.h" #include "xfs_lowlevel.h" #include "DMAPI.h" char* fs_lowlevel::init_dmapi(void) { char *v; v = FS_DMAPI::init_dmapi(); printf("fs_lowlevel: v : %s\n", v); return v; } void fs_lowlevel::print_objtype() { FS_DMAPI::print_objtype(); } fs_lowlevel::fs_lowlevel() { #if 0 fprintf(stdout, "Creating DMAPI object for FS %s\n", fs); po_dm = DMAPI::create(fs); #endif } fs_lowlevel::~fs_lowlevel() { #if 0 delete po_dm; #endif } #if 0 char* fs_lowlevel::init_dmapi(void) { return(po_dm->init_dmapi()); } void fs_lowlevel::print_objtype() { po_dm->print_objtype(); } #endif ======================================= end fs_lowlevel.cpp begin fs_lowlevel.h =========== #ifndef FS_LOWLEVEL_H #define FS_LOWLEVEL_H #include "DMAPI.h" class fs_lowlevel : public lowlevel { public: char* init_dmapi(void); void print_objtype(void); }; #endif ======================================= end fs_lowlevel.h begin GPFS_DMAPI.h =========== #ifndef GPFS_DMAPI_H #define GPFS_DMAPI_H #include <stdio.h> #include <string.h> namespace GPFS_DMAPI { char* init_dmapi(void); void print_objtype(void); /*static*/ char *dmapi_ver; /*static*/ char *logfile; /*static*/ FILE *logfp; }; #if 0 char* GPFS_DMAPI::logfile="/tmp/gpfsdmapi.log"; char* GPFS_DMAPI::dmapi_ver=NULL; FILE* GPFS_DMAPI::logfp=NULL; #endif #endif /* DMAPI_H */ ======================================= end GPFS_DMAPI.h begin gpfs_lowlevel.h =========== #ifndef GPFS_LOWLEVEL_H #define GPFS_LOWLEVEL_H #include "DMAPI.h" class gpfs_lowlevel : public lowlevel { public: gpfs_lowlevel(); ~gpfs_lowlevel(); char* init_dmapi(void); void print_objtype(void); }; #endif ======================================= end gpfs_lowlevel.h begin JFS_DMAPI.h =========== #ifndef JFS_DMAPI_H #define JFS_DMAPI_H #include <stdio.h> #include <string.h> namespace JFS_DMAPI { char* init_dmapi(void); void print_objtype(void); /* making these variables /*static*/ does not work for some reason */ /*static*/ char *dmapi_ver; /*static*/ char *logfile; /*static*/ FILE *logfp; }; #if 0 static char* JFS_DMAPI::logfile="/tmp/gpfsdmapi.log"; static char* JFS_DMAPI::dmapi_ver=NULL; static FILE* JFS_DMAPI::logfp=NULL; #endif #endif /* DMAPI_H */ ======================================= end JFS_DMAPI.h begin jfs_lowlevel.h =========== #ifndef JFS_LOWLEVEL_H #define JFS_LOWLEVEL_H #include "DMAPI.h" class jfs_lowlevel : public lowlevel { public: jfs_lowlevel(); ~jfs_lowlevel(); char* init_dmapi(void); void print_objtype(void); }; #endif ======================================= end jfs_lowlevel.h begin lowlevel.cpp =========== #include<stdio.h> #include "lowlevel.h" #include "gpfs_lowlevel.h" #include "xfs_lowlevel.h" #include <string.h> #define JFS 0 #define GPFS 1 /* main() { lowlevel *pobj; lowlevel *pobj1; pobj = lowlevel::create(0); pobj->init_dmapi(); pobj1 = lowlevel::create(1); pobj1->init_dmapi(); pobj->get_print_token(); pobj1->get_print_token(); } */ lowlevel* lowlevel :: create(char* fs) { lowlevel *pd; if (!strcasecmp(fs, "gpfs")) { printf("creating gpfs lowlevel obj\n"); pd = new gpfs_lowlevel(); } if (!strcasecmp(fs, "xfs")) { printf("creating xfs lowlevbel obj\n"); pd = new xfs_lowlevel(); } return pd; } ======================================= end lowlevel.cpp begin lowlevel.h =========== #ifndef LOWLEVEL_H #define LOWLEVEL_H #include<stdio.h> class lowlevel { public: static lowlevel* create(char *fstype); virtual char* init_dmapi(void) = 0; virtual void print_objtype(void) = 0; }; #endif ======================================= end lowlevel.h begin main.cpp =========== #include<stdio.h> #include "lowlevel.h" #if 0 #include "JFS_DMAPI.h" #include "GPFS_DMAPI.h" #endif main() { lowlevel *pobj, *pobj1; pobj = lowlevel::create("xfs"); if (pobj != NULL) { pobj->init_dmapi(); pobj->print_objtype(); } else { printf("pobj is NULL\n"); } char *a = new char; pobj1 = lowlevel::create("gpfs"); pobj1->init_dmapi(); pobj1->print_objtype(); #if 0 JFS_DMAPI pobj; GPFS_DMAPI pobj1; pobj.init_dmapi(); pobj1.init_dmapi(); #endif } ======================================= end main.cpp begin xfs_lowlevel.h =========== #ifndef XFS_LOWLEVEL_H #define XFS_LOWLEVEL_H #include "DMAPI.h" class xfs_lowlevel : public lowlevel { public: xfs_lowlevel(); ~xfs_lowlevel(); char* init_dmapi(void); void print_objtype(void); }; #endif ======================================= end xfs_lowlevel.h Makefile ======================================= # makefile w/o rtl + with namespace ROOTDIR=`pwd`/.. CURDIR=`pwd` BINDIR=`pwd` #OPT="-qexpfile=" #OPT=-bE: OPT=--version-script= CC=/usr/bin/gcc #create fs specific header files. I am not doign that here. That needs #to be done. #create the FS specific .o ${CC} -c -fPIC -frepo -g -DFS_DMAPI=XFS_DMAPI -DXFSDMAPI -o XFSDMAPI.o DMAPI.cpp ${CC} -c -fPIC -frepo -g -DFS_DMAPI=GPFS_DMAPI -DGPFSDMAPI -o GPFSDMAPI.o DMAPI.cpp #create the fs specific DMAPI library. #create the exports file g++ -shared -fPIC ${OPT}xfs_mapfile -frepo -pthread -DUNIX -D_PTHREADS -DCV_POSIX_THREADS -DPOSIX_THREADS -D_FILE_OFFSET_BITS=64 -DLINUX_FS_U -DENABLE_NAS -DENABLE_DMR -DENABLE_DMAPI -DENABLE_CDR -DUNIX -Dunix -DNO_JM_EXCEPTIONS -DNO_RSM -DNO_MMALERTS -DMAX_PATH=1024 -DCARCH=32 -Wimplicit -Wchar-subscripts -Wformat -Wpointer-arith -Wno-deprecated -Wconversion -Wmissing-noreturn -DCV_LITTLE_ENDIAN -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONGLONG=8 -DSOCKLEN_T.acklen_t -DFDSET=fd_set -DHAVE_ERRNO_H -DHAVE_GRANTPT -DNO_GETOPT -DHAVE_GETHOSTNAME -DGETHOSTBYNAME_R_6 -DGETSERVBYNAME_R_6 -DNO_LONGLONG_T -DNO_U_LONGLONG_T -DTIME_R_RET_TM -DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2 -DSTRTOK_R3 -DPWNAM_R5 -DHAVE_VFS -DNO_USHORT_T -DNO_UINT_T -DHAVE_X_PUTINT32 -DATFORK_ARG=void -DLINUX_ACL -gstabs+ -Wl,-rpath-link=. -Wl,-rpath=. -L. -shared -shared-libgcc XFSDMAPI.o -L. -L/lib -o libXFSDMAPI.so -ldm g++ -shared -fPIC ${OPT}gpfs_mapfile -frepo -pthread -DUNIX -D_PTHREADS -DCV_POSIX_THREADS -DPOSIX_THREADS -D_FILE_OFFSET_BITS=64 -DLINUX_FS_U -DENABLE_NAS -DENABLE_DMR -DENABLE_DMAPI -DENABLE_CDR -DUNIX -Dunix -DNO_JM_EXCEPTIONS -DNO_RSM -DNO_MMALERTS -DMAX_PATH=1024 -DCARCH=32 -Wimplicit -Wchar-subscripts -Wformat -Wpointer-arith -Wno-deprecated -Wconversion -Wmissing-noreturn -DCV_LITTLE_ENDIAN -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONGLONG=8 -DSOCKLEN_T.acklen_t -DFDSET=fd_set -DHAVE_ERRNO_H -DHAVE_GRANTPT -DNO_GETOPT -DHAVE_GETHOSTNAME -DGETHOSTBYNAME_R_6 -DGETSERVBYNAME_R_6 -DNO_LONGLONG_T -DNO_U_LONGLONG_T -DTIME_R_RET_TM -DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2 -DSTRTOK_R3 -DPWNAM_R5 -DHAVE_VFS -DNO_USHORT_T -DNO_UINT_T -DHAVE_X_PUTINT32 -DATFORK_ARG=void -DLINUX_ACL -gstabs+ -Wl,-rpath-link=. -Wl,-rpath=. -L. -shared -shared-libgcc GPFSDMAPI.o -L. -o libGPFSDMAPI.so -ldmapi #${CC} -qmkshrobj -g -Wl,-bh:5 -qchars=signed -qinfo=pro -qcpluscmt -DUNIX -Dunix -D_SVID3 -DAIX_FS_U -Dmthreads -DCV_POSIX_THREADS -DPOSIX_THREADS -D_PTHREADS -D_THREAD_SAFE -D_LARGE_FILES -DENABLE_NAS -DENABLE_DMAPI -DENABLE_DMR -Daix -DUNIX -Dunix -DNO_JM_EXCEPTIONS -DNO_RSM -DNO_MMALERTS -DMAX_PATH=1024 -DCARCH=32 -DCV_BIG_ENDIAN -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONGLONG=8 -DSOCKLEN_T=socklen_t -DFDSET=fd_set -DHAVE_ERRNO_H -DHAVE_GRANTPT -DCONST_ICONV_IPTR -DHAVE_GETHOSTNAME -DGETHOSTBYNAME_R_3 -DGETSERVBYNAME_R_4 -DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2 -DSTRTOK_R3 -DPWNAM_R5 -DHAVE_VFS -DHAVE_X_PUTINT32 -DHAVE_X_PUTHYPER -DATFORK_ARG=void -DSOCKADDR_FAMILY_AT_2ND_BYTE -L${BINDIR} -o libDMAPI.so -lGPFSDMAPI -lJFSDMAPI ${CC} -c -fPIC -frepo -g -Dfs_lowlevel=xfs_lowlevel -DXFSLOWLEVEL -DFS_DMAPI=XFS_DMAPI -DXFSDMAPI -o XFSLOWLEVEL.o fs_lowlevel.cpp ${CC} -c -fPIC -frepo -g -Dfs_lowlevel=gpfs_lowlevel -DGPFSLOWLEVEL -DFS_DMAPI=GPFS_DMAPI -DGPFSDMAPI -o GPFSLOWLEVEL.o fs_lowlevel.cpp #create the fs specific DMAPI library. #create the exports file g++ -shared -fPIC ${OPT}xfs_llmapfile -frepo -pthread -DUNIX -D_PTHREADS -DCV_POSIX_THREADS -DPOSIX_THREADS -D_FILE_OFFSET_BITS=64 -DLINUX_FS_U -DENABLE_NAS -DENABLE_DMR -DENABLE_DMAPI -DENABLE_CDR -DUNIX -Dunix -DNO_JM_EXCEPTIONS -DNO_RSM -DNO_MMALERTS -DMAX_PATH=1024 -DCARCH=32 -Wimplicit -Wchar-subscripts -Wformat -Wpointer-arith -Wno-deprecated -Wconversion -Wmissing-noreturn -DCV_LITTLE_ENDIAN -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONGLONG=8 -DSOCKLEN_T=socklen_t -DFDSET=fd_set -DHAVE_ERRNO_H -DHAVE_GRANTPT -DNO_GETOPT -DHAVE_GETHOSTNAME -DGETHOSTBYNAME_R_6 -DGETSERVBYNAME_R_6 -DNO_LONGLONG_T -DNO_U_LONGLONG_T -DTIME_R_RET_TM -DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2 -DSTRTOK_R3 -DPWNAM_R5 -DHAVE_VFS -DNO_USHORT_T -DNO_UINT_T -DHAVE_X_PUTINT32 -DATFORK_ARG=void -DLINUX_ACL -gstabs+ -Wl,-rpath-link=. -Wl,-rpath=. -shared-libgcc XFSLOWLEVEL.o -L. -o libXFSLOWLEVEL.so -lXFSDMAPI g++ -shared -fPIC ${OPT}gpfs_llmapfile -frepo -pthread -DUNIX -D_PTHREADS -DCV_POSIX_THREADS -DPOSIX_THREADS -D_FILE_OFFSET_BITS=64 -DLINUX_FS_U -DENABLE_NAS -DENABLE_DMR -DENABLE_DMAPI -DENABLE_CDR -DUNIX -Dunix -DNO_JM_EXCEPTIONS -DNO_RSM -DNO_MMALERTS -DMAX_PATH=1024 -DCARCH=32 -Wimplicit -Wchar-subscripts -Wformat -Wpointer-arith -Wno-deprecated -Wconversion -Wmissing-noreturn -DCV_LITTLE_ENDIAN -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONGLONG=8 -DSOCKLEN_T=socklen_t -DFDSET=fd_set -DHAVE_ERRNO_H -DHAVE_GRANTPT -DNO_GETOPT -DHAVE_GETHOSTNAME -DGETHOSTBYNAME_R_6 -DGETSERVBYNAME_R_6 -DNO_LONGLONG_T -DNO_U_LONGLONG_T -DTIME_R_RET_TM -DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2 -DSTRTOK_R3 -DPWNAM_R5 -DHAVE_VFS -DNO_USHORT_T -DNO_UINT_T -DHAVE_X_PUTINT32 -DATFORK_ARG=void -DLINUX_ACL -gstabs+ -Wl,-rpath-link=. -Wl,-rpath=. -shared-libgcc GPFSLOWLEVEL.o -L. -o libGPFSLOWLEVEL.so -lGPFSDMAPI g++ -shared -fPIC ${OPT}ll_mapfile -frepo -pthread -DUNIX -D_PTHREADS -DCV_POSIX_THREADS -DPOSIX_THREADS -D_FILE_OFFSET_BITS=64 -DLINUX_FS_U -DENABLE_NAS -DENABLE_DMR -DENABLE_DMAPI -DENABLE_CDR -DUNIX -Dunix -DNO_JM_EXCEPTIONS -DNO_RSM -DNO_MMALERTS -DMAX_PATH=1024 -DCARCH=32 -Wimplicit -Wchar-subscripts -Wformat -Wpointer-arith -Wno-deprecated -Wconversion -Wmissing-noreturn -DCV_LITTLE_ENDIAN -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONGLONG=8 -DSOCKLEN_T=socklen_t -DFDSET=fd_set -DHAVE_ERRNO_H -DHAVE_GRANTPT -DNO_GETOPT -DHAVE_GETHOSTNAME -DGETHOSTBYNAME_R_6 -DGETSERVBYNAME_R_6 -DNO_LONGLONG_T -DNO_U_LONGLONG_T -DTIME_R_RET_TM -DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2 -DSTRTOK_R3 -DPWNAM_R5 -DHAVE_VFS -DNO_USHORT_T -DNO_UINT_T -DHAVE_X_PUTINT32 -DATFORK_ARG=void -DLINUX_ACL -gstabs+ -Wl,-rpath-link=. -Wl,-rpath=. -L. -shared-libgcc -I${ROOTDIR}/DMAPI -L${BINDIR} -o libLOWLEVEL.so lowlevel.cpp -lGPFSLOWLEVEL -lXFSLOWLEVEL g++ -pthread -fPIC -DUNIX -D_PTHREADS -DCV_POSIX_THREADS -DPOSIX_THREADS -DLINUX_FS_U -DENABLE_NAS -DENABLE_DMR -DENABLE_DMAPI -DENABLE_CDR -DUNIX -Dunix -DNO_JM_EXCEPTIONS -DNO_RSM -DNO_MMALERTS -DMAX_PATH=1024 -DCARCH=32 -Wimplicit -Wchar-subscripts -Wformat -Wpointer-arith -Wno-deprecated -Wconversion -Wmissing-noreturn -DCV_LITTLE_ENDIAN -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONGLONG=8 -DSOCKLEN_T=socklen_t -DFDSET=fd_set -DHAVE_ERRNO_H -DHAVE_GRANTPT -DNO_GETOPT -DHAVE_GETHOSTNAME -DGETHOSTBYNAME_R_6 -DGETSERVBYNAME_R_6 -DNO_LONGLONG_T -DNO_U_LONGLONG_T -DTIME_R_RET_TM -DCTIME2 -DGMTIME_R2 -DLOCALTIME_R2 -DSTRTOK_R3 -DPWNAM_R5 -DHAVE_VFS -DNO_USHORT_T -DNO_UINT_T -DHAVE_X_PUTINT32 -DATFORK_ARG=void -DLINUX_ACL -gstabs+ -Wl,-rpath-link=. -Wl,-rpath=. -L. -shared-libgcc -L${BINDIR} -o main main.cpp -lLOWLEVEL ========================================================== end of Makefile