Eric B Munson wrote:
> On Tue, 28 Dec 2010, Andrew Hastings wrote:
> 
>> libhugetlbfs redefines shmget() so that it can transparently optionally
>> add the hugepage flag.  Unfortunately, it uses dlsym() to to find the
>> next shmget() to call in the dynamic library call chain.  This does not
>> work on statically-linked executables.
>>
>> Work around this by making all references to libdl weak, and testing
>> for its presence.  If libdl symbols are not not present, directly
>> make the shmget syscall.
>>
>> Making the dl* symbols weak does not affect dynamic executables as
>> libdl.so is:
>> * Automatically added to the library dependency list when liked with
>>   -lhugetlbfs
>> * Mapped into the programs address space when used with LD_PRELOAD.
>>
>> Based on a patch originally authored by Dean Luick <lu...@cray.com>.
>>
>> Signed-off-by: Andrew Hastings <a...@cray.com> on behalf of Cray Inc.
>> ---
>>
>> -Andrew Hastings
>>  Cray Inc.
>>
>> diff -ruNp libhugetlbfs-2.11/shm.c libhugetlbfs-2.11-shm/shm.c
>> --- libhugetlbfs-2.11/shm.c  2010-12-16 11:38:22.000000000 -0600
>> +++ libhugetlbfs-2.11-shm/shm.c      2010-12-28 17:26:00.725063000 -0600
>> @@ -29,6 +29,37 @@
>>  #include "libhugetlbfs_internal.h"
>>  #include "hugetlbfs.h"
>>  
>> +#if defined(__x86_64)
> 
> Why is this patch x86_64 specific, does it not work for x86, or ppc64, or any
> other arch we support?  I am reluctant to take functionality like this for
> a single arch unless there is no way to make it work elsewhere.

ia32 doesn't have a SYS_shmget system call; instead shmget gets funneled 
through SYS_ipc and the definitions needed to use it are not available outside 
glibc.

We no longer have a way to test on ppc or ppc64, unfortunately.

-Andrew Hastings
 Cray Inc.

> 
>> +/*
>> + * The calls to dlsym() and dlerror() in the shmget() wrapper below force
>> + * a dependency on libdl.so.  This does not work for static executables
>> + * as the glibc dynamic library implementation does not automatically
>> + * have static dl* function stubs linked into static executables.
>> + *
>> + * Work around this problem by adding a weak attribute to the declarations
>> + * of dlsym() and dlerror().  (The declaration is otherwise the same as in
>> + * <dlfcn.h>).  This allows a static executable to be linked without -ldl.
>> + * If &dlsym is NULL then this is a static executable and a call to the
>> + * system shmget() may be performed without worry as there is no dynamic
>> + * call chain.
>> + *
>> + * Although this problem appears to be platform-independent, the solution
>> + * unfortunately depends on the platform, thus the __x86_64 ifdef.
>> + */
>> +#include <sys/syscall.h>    /* for SYS_xxx definitions */
>> +
>> +extern void *dlsym (void *__restrict __handle, __const char *__restrict 
>> __name)
>> +            __attribute__((weak)) __THROW __nonnull ((2));
>> +extern char *dlerror (void) __attribute__((weak)) __THROW;
>> +
>> +
>> +/* call syscall shmget through the generic syscall mechanism */
>> +static int syscall_shmget(key_t key, size_t size, int shmflg)
>> +{
>> +    return syscall(SYS_shmget, key, size, shmflg);
>> +}
>> +#endif /* __x86_64 */
>> +
>>  int shmget(key_t key, size_t size, int shmflg)
>>  {
>>      static int (*real_shmget)(key_t key, size_t size, int shmflg) = NULL;
>> @@ -40,10 +71,18 @@ int shmget(key_t key, size_t size, int s
>>  
>>      /* Get a handle to the "real" shmget system call */
>>      if (!real_shmget) {
>> -            real_shmget = dlsym(RTLD_NEXT, "shmget");
>> -            if ((error = dlerror()) != NULL) {
>> -                    ERROR("%s", error);
>> -                    return -1;
>> +#if defined(__x86_64)
>> +            if (&dlsym == NULL) {
>> +                    /* in a static executable, call shmget directly */
>> +                    real_shmget = syscall_shmget;
>> +            } else
>> +#endif /* __x86_64 */
>> +            {
>> +                    real_shmget = dlsym(RTLD_NEXT, "shmget");
>> +                    if ((error = dlerror()) != NULL) {
>> +                            ERROR("%s", error);
>> +                            return -1;
>> +                    }
>>              }
>>      }
>>  
>>
>> ------------------------------------------------------------------------------
>> Learn how Oracle Real Application Clusters (RAC) One Node allows customers
>> to consolidate database storage, standardize their database environment, 
>> and, 
>> should the need arise, upgrade to a full multi-node Oracle RAC database 
>> without downtime or disruption
>> http://p.sf.net/sfu/oracle-sfdevnl
>> _______________________________________________
>> Libhugetlbfs-devel mailing list
>> Libhugetlbfs-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel
>>


------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and, 
should the need arise, upgrade to a full multi-node Oracle RAC database 
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
Libhugetlbfs-devel mailing list
Libhugetlbfs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel

Reply via email to