his patch removes the various functions which use the seg_info structure from hugeutils.c to elflink.c which is the only place they're used. While we're at it, move in the seg_info definition itself from the .h file, make things static which now can be and re-arrange functions to avoid forward declarations.
elflink.c | 301 ++++++++++++++++++++++++++++++++++++++++++++++++ hugetlbd.h | 2 hugeutils.c | 296 ----------------------------------------------- libhugetlbfs_internal.h | 10 - 4 files changed, 303 insertions(+), 306 deletions(-) Index: libhugetlbfs/elflink.c =================================================================== --- libhugetlbfs.orig/elflink.c 2006-10-13 15:20:42.000000000 +1000 +++ libhugetlbfs/elflink.c 2006-10-13 16:14:38.000000000 +1000 @@ -25,7 +25,13 @@ #include <malloc.h> #include <string.h> #include <signal.h> +#include <unistd.h> +#include <fcntl.h> #include <sys/syscall.h> +#include <sys/ipc.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> #include <linux/unistd.h> #include <sys/mman.h> #include <errno.h> @@ -34,6 +40,7 @@ #include "hugetlbfs.h" #include "libhugetlbfs_internal.h" +#include "hugetlbd.h" #ifdef __LP64__ #define Elf_Ehdr Elf64_Ehdr @@ -179,12 +186,22 @@ static void unmapped_abort(const char *f #define MAX_HTLB_SEGS 2 +struct seg_info { + void *vaddr; + unsigned long filesz, memsz; + int prot; + int fd; +}; + static struct seg_info htlb_seg_table[MAX_HTLB_SEGS]; static int htlb_num_segs; static int minimal_copy = 1; int __debug = 0; static Elf_Ehdr *ehdr; +static int sock; +static int timeout; + static void parse_phdrs(Elf_Ehdr *ehdr) { Elf_Phdr *phdr = (Elf_Phdr *)((char *)ehdr + ehdr->e_phoff); @@ -230,6 +247,290 @@ static void parse_phdrs(Elf_Ehdr *ehdr) } } +/** + * create_id - create unique id for current executable + * + * Uses IPC ftok() to generate a roughly unique identifier for our own + * executable. This is used to match shareable mappings. + * + * returns: -1, on error + * a unique identifier, otherwise + */ +static exe_ident_t create_id(void) +{ + exe_ident_t id; + int ret; + char my_exe[PATH_MAX]; + + ret = readlink("/proc/self/exe", my_exe, PATH_MAX); + if (ret < 0) { + ERROR("readlink failed: %s\n", strerror(errno)); + return -1; + } + + id = (exe_ident_t)ftok(my_exe, ID_KEY); + if (id < 0) { + ERROR("ftok failed: %s\n", strerror(errno)); + return -1; + } + + return id; +} + +static void signal_handler(int signal) +{ + switch (signal) { + case SIGALRM: + timeout = 1; + } +} + +/** + * client_complete - send ACK to daemon that we no longer need file + * @htlb_seg_info: pointer to program's segment data + * @success: if 0, successful prepare, else failed + * + * returns: 0, if successful transmission (none occurs if + * not sharing) + * -1, if failed transmission + */ +static int client_complete(struct seg_info *htlb_seg_info, int success) +{ + struct sigaction sigact = { + .sa_handler = signal_handler, + .sa_flags = 0, + }; + struct sigaction prev; + struct client_response cresp; + int ret; + + sigemptyset(&(sigact.sa_mask)); + + sigaction(SIGALRM, &sigact, &prev); + + cresp.succeeded = success; + + alarm(60); + ret = write(sock, &cresp, sizeof(cresp)); + alarm(0); + if (ret < 0) { + if (timeout) { + DEBUG("write timed out\n"); + goto fail; + } else { + ERROR("client response write failed: %s\n", + strerror(errno)); + goto fail; + } + } else if (ret != sizeof(cresp)) { + DEBUG("short write (got %d, should have been %zu)\n", + ret, sizeof(cresp)); + goto fail; + } /* else successfully wrote */ + + sigaction(SIGALRM, &prev, NULL); + + if (success < 0) + /* back out open'd fd since we failed */ + close(htlb_seg_info->fd); + + close(sock); + return 0; + +fail: + close(htlb_seg_info->fd); + close(sock); + return -1; +} + +/** + * hugetlbfs_shared_file - communicate with daemon to get one shareable file + * @htlb_seg_info: pointer to program's segment data + * + * returns: + * -1, on failure + * 0, on success, and caller does not need to prepare the segments + * 1, on success, and caller does need to prepare the segments + */ +static int hugetlbfs_shared_file(struct seg_info *htlb_seg_info) +{ + int ret, fd; + struct client_request creq; + struct daemon_response dresp; + struct sockaddr_un sun; + struct sigaction sigact = { + .sa_handler = signal_handler, + .sa_flags = 0, + }; + struct sigaction prev; + int open_flags; + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + ERROR("socket() failed: %s\n", strerror(errno)); + return -1; + } + + sun.sun_family = AF_UNIX; + strcpy(sun.sun_path, "/tmp/libhugetlbfs-sock"); + ret = connect(sock, &sun, sizeof(sun)); + if (ret < 0) { + ERROR("connect() failed: %s\n", strerror(errno)); + return -1; + } + + sigemptyset(&(sigact.sa_mask)); + + sigaction(SIGALRM, &sigact, &prev); + + /* add data to request */ + creq.id = create_id(); + /* + * This results in (non-harmful) compilation warning for + * 32-bit applications + */ + creq.vaddr = (vaddr_t)htlb_seg_info->vaddr; + + alarm(60); + ret = write(sock, &creq, sizeof(creq)); + /* cancel any alarms */ + alarm(0); + if (ret < 0) { + if (timeout) { + DEBUG("write timed out\n"); + goto fail; + } else { + ERROR("client request write failed: %s\n", + strerror(errno)); + goto fail; + } + } else if (ret != sizeof(creq)) { + DEBUG("short write (got %d, should have been %zu)\n", + ret, sizeof(creq)); + goto fail; + } /* else successfully wrote */ + + /* wait slightly longer for the response */ + alarm(120); + ret = read(sock, &dresp, sizeof(dresp)); + alarm(0); + if (ret < 0) { + if (timeout) { + DEBUG("read timed out\n"); + goto fail; + } else { + ERROR("read failed: %s\n", strerror(errno)); + goto fail; + } + } else if (ret != sizeof(dresp)) { + DEBUG("short read (got %d, should have been %zu)\n", + ret, sizeof(dresp)); + goto fail; + } /* else successfully read */ + + sigaction(SIGALRM, &prev, NULL); + + /* Convert daemon response to open mode bits */ + if (dresp.need_to_prepare) { + open_flags = O_RDWR; + } else { + open_flags = O_RDONLY; + } + + /* get local handle on file */ + fd = open(dresp.path_to_file, open_flags); + if (fd < 0) { + ERROR("open(%s) failed: %s\n", dresp.path_to_file, + strerror(errno)); + goto fail; + } + + if (dresp.need_to_prepare) { + DEBUG("daemon said to prepare\n"); + } else { + /* ACK right away (closes socket) */ + DEBUG("daemon said not to prepare\n"); + ret = client_complete(htlb_seg_info, 0); + if (ret < 0) + goto fail; + } + + htlb_seg_info->fd = fd; + + /* leave socket open until finished_prepare is called */ + return dresp.need_to_prepare; + +fail: + close(sock); + return -1; +} + +/** + * finished_prepare - callback for ACK'ing prepare is done + * @htlb_seg_info: pointer to program's segment data + * @success: if 0, successful prepare, else failed + * + * returns: 0, if successful transmission (none occurs if + * not sharing) + * -1, if failed transmission + */ +static int finished_prepare(struct seg_info *htlb_seg_info, int success) +{ + if (sharing) + return client_complete(htlb_seg_info, success); + return 0; +} + +/** + * hugetlbfs_set_fds - multiplex callers depending on if sharing or not + * @htlb_seg_info: pointer to program's segment data + * + * returns: + * -1, on error + * 0, on success, caller expects and gets shared, does not need to prepare + * 1, on success, caller expects and gets shared, does need to prepare + * 2, on success, caller expects shared and gets unlinked, does need to prepare + * 3, on success, caller expects and gets unlinked, does need to prepare + */ +static int hugetlbfs_set_fd(struct seg_info *htlb_seg_info) +{ + char *env; + int fd; + /* assume unlinked, all unlinked files need to be prepared */ + int ret = 3; + + env = getenv("HUGETLB_SHARE"); + if (env) + sharing = atoi(env); + DEBUG("HUGETLB_SHARE=%d, sharing ", sharing); + if (sharing == 2) { + DEBUG_CONT("enabled for all segments\n"); + } else { + if (sharing == 1) { + DEBUG_CONT("enabled for only read-only segments\n"); + } else { + DEBUG_CONT("disabled\n"); + } + } + + /* Either share all segments or share only read-only segments */ + if ((sharing == 2) || ((sharing == 1) && + !(htlb_seg_info->prot & PROT_WRITE))) { + /* first, try to share */ + ret = hugetlbfs_shared_file(htlb_seg_info); + if (ret >= 0) + return ret; + /* but, fall through to unlinked files, if sharing fails */ + ret = 2; + DEBUG("Falling back to unlinked files\n"); + } + fd = hugetlbfs_unlinked_fd(); + if (fd < 0) + return -1; + htlb_seg_info->fd = fd; + return ret; +} + static void check_bss(unsigned long *start, unsigned long *end) { unsigned long *addr; Index: libhugetlbfs/hugetlbd.h =================================================================== --- libhugetlbfs.orig/hugetlbd.h 2006-09-04 17:08:33.000000000 +1000 +++ libhugetlbfs/hugetlbd.h 2006-10-13 16:04:42.000000000 +1000 @@ -20,6 +20,8 @@ #ifndef _HUGETLBD_H #define _HUGETLBD_H +#include <limits.h> + #ifndef __LIBHUGETLBFS__ #error This header should not be included by library users. #endif /* __LIBHUGETLBFS__ */ Index: libhugetlbfs/hugeutils.c =================================================================== --- libhugetlbfs.orig/hugeutils.c 2006-10-13 12:06:55.000000000 +1000 +++ libhugetlbfs/hugeutils.c 2006-10-13 16:06:53.000000000 +1000 @@ -35,15 +35,10 @@ #include <fcntl.h> #include <sys/vfs.h> #include <sys/statfs.h> -#include <sys/types.h> -#include <sys/ipc.h> -#include <sys/socket.h> -#include <sys/un.h> #include <sys/mman.h> #include "libhugetlbfs_internal.h" #include "hugetlbfs.h" -#include "hugetlbd.h" static int hpage_size; /* = 0 */ static char htlb_mount[PATH_MAX+1]; /* = 0 */ @@ -247,297 +242,6 @@ int hugetlbfs_unlinked_fd(void) return fd; } -/** - * create_id - create unique id for current executable - * - * Uses IPC ftok() to generate a roughly unique identifier for our own - * executable. This is used to match shareable mappings. - * - * returns: -1, on error - * a unique identifier, otherwise - */ -static exe_ident_t create_id(void) -{ - exe_ident_t id; - int ret; - char my_exe[PATH_MAX]; - - ret = readlink("/proc/self/exe", my_exe, PATH_MAX); - if (ret < 0) { - ERROR("readlink failed: %s\n", strerror(errno)); - return -1; - } - - id = (exe_ident_t)ftok(my_exe, ID_KEY); - if (id < 0) { - ERROR("ftok failed: %s\n", strerror(errno)); - return -1; - } - - return id; -} - -static int sock; -static int timeout; -/* global to allow multiple callsites to set members */ - -static void signal_handler(int signal) -{ - switch (signal) { - case SIGALRM: - timeout = 1; - } -} - -static int client_complete(struct seg_info *htlb_seg_info, int success); - -/** - * hugetlbfs_shared_file - communicate with daemon to get one shareable file - * @htlb_seg_info: pointer to program's segment data - * - * returns: - * -1, on failure - * 0, on success, and caller does not need to prepare the segments - * 1, on success, and caller does need to prepare the segments - */ -static int hugetlbfs_shared_file(struct seg_info *htlb_seg_info) -{ - int ret, fd; - struct client_request creq; - struct daemon_response dresp; - struct sockaddr_un sun; - struct sigaction sigact = { - .sa_handler = signal_handler, - .sa_flags = 0, - }; - struct sigaction prev; - int open_flags; - - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - ERROR("socket() failed: %s\n", strerror(errno)); - return -1; - } - - sun.sun_family = AF_UNIX; - strcpy(sun.sun_path, "/tmp/libhugetlbfs-sock"); - ret = connect(sock, &sun, sizeof(sun)); - if (ret < 0) { - ERROR("connect() failed: %s\n", strerror(errno)); - return -1; - } - - sigemptyset(&(sigact.sa_mask)); - - sigaction(SIGALRM, &sigact, &prev); - - /* add data to request */ - creq.id = create_id(); - /* - * This results in (non-harmful) compilation warning for - * 32-bit applications - */ - creq.vaddr = (vaddr_t)htlb_seg_info->vaddr; - - alarm(60); - ret = write(sock, &creq, sizeof(creq)); - /* cancel any alarms */ - alarm(0); - if (ret < 0) { - if (timeout) { - DEBUG("write timed out\n"); - goto fail; - } else { - ERROR("client request write failed: %s\n", - strerror(errno)); - goto fail; - } - } else if (ret != sizeof(creq)) { - DEBUG("short write (got %d, should have been %zu)\n", - ret, sizeof(creq)); - goto fail; - } /* else successfully wrote */ - - /* wait slightly longer for the response */ - alarm(120); - ret = read(sock, &dresp, sizeof(dresp)); - alarm(0); - if (ret < 0) { - if (timeout) { - DEBUG("read timed out\n"); - goto fail; - } else { - ERROR("read failed: %s\n", strerror(errno)); - goto fail; - } - } else if (ret != sizeof(dresp)) { - DEBUG("short read (got %d, should have been %zu)\n", - ret, sizeof(dresp)); - goto fail; - } /* else successfully read */ - - sigaction(SIGALRM, &prev, NULL); - - /* Convert daemon response to open mode bits */ - if (dresp.need_to_prepare) { - open_flags = O_RDWR; - } else { - open_flags = O_RDONLY; - } - - /* get local handle on file */ - fd = open(dresp.path_to_file, open_flags); - if (fd < 0) { - ERROR("open(%s) failed: %s\n", dresp.path_to_file, - strerror(errno)); - goto fail; - } - - if (dresp.need_to_prepare) { - DEBUG("daemon said to prepare\n"); - } else { - /* ACK right away (closes socket) */ - DEBUG("daemon said not to prepare\n"); - ret = client_complete(htlb_seg_info, 0); - if (ret < 0) - goto fail; - } - - htlb_seg_info->fd = fd; - - /* leave socket open until finished_prepare is called */ - return dresp.need_to_prepare; - -fail: - close(sock); - return -1; -} - -/** - * client_complete - send ACK to daemon that we no longer need file - * @htlb_seg_info: pointer to program's segment data - * @success: if 0, successful prepare, else failed - * - * returns: 0, if successful transmission (none occurs if - * not sharing) - * -1, if failed transmission - */ -static int client_complete(struct seg_info *htlb_seg_info, int success) -{ - struct sigaction sigact = { - .sa_handler = signal_handler, - .sa_flags = 0, - }; - struct sigaction prev; - struct client_response cresp; - int ret; - - sigemptyset(&(sigact.sa_mask)); - - sigaction(SIGALRM, &sigact, &prev); - - cresp.succeeded = success; - - alarm(60); - ret = write(sock, &cresp, sizeof(cresp)); - alarm(0); - if (ret < 0) { - if (timeout) { - DEBUG("write timed out\n"); - goto fail; - } else { - ERROR("client response write failed: %s\n", - strerror(errno)); - goto fail; - } - } else if (ret != sizeof(cresp)) { - DEBUG("short write (got %d, should have been %zu)\n", - ret, sizeof(cresp)); - goto fail; - } /* else successfully wrote */ - - sigaction(SIGALRM, &prev, NULL); - - if (success < 0) - /* back out open'd fd since we failed */ - close(htlb_seg_info->fd); - - close(sock); - return 0; - -fail: - close(htlb_seg_info->fd); - close(sock); - return -1; -} - -/** - * finished_prepare - callback for ACK'ing prepare is done - * @htlb_seg_info: pointer to program's segment data - * @success: if 0, successful prepare, else failed - * - * returns: 0, if successful transmission (none occurs if - * not sharing) - * -1, if failed transmission - */ -int finished_prepare(struct seg_info *htlb_seg_info, int success) -{ - if (sharing) - return client_complete(htlb_seg_info, success); - return 0; -} - -/** - * hugetlbfs_set_fds - multiplex callers depending on if sharing or not - * @htlb_seg_info: pointer to program's segment data - * - * returns: - * -1, on error - * 0, on success, caller expects and gets shared, does not need to prepare - * 1, on success, caller expects and gets shared, does need to prepare - * 2, on success, caller expects shared and gets unlinked, does need to prepare - * 3, on success, caller expects and gets unlinked, does need to prepare - */ -int hugetlbfs_set_fd(struct seg_info *htlb_seg_info) -{ - char *env; - int fd; - /* assume unlinked, all unlinked files need to be prepared */ - int ret = 3; - - env = getenv("HUGETLB_SHARE"); - if (env) - sharing = atoi(env); - DEBUG("HUGETLB_SHARE=%d, sharing ", sharing); - if (sharing == 2) { - DEBUG_CONT("enabled for all segments\n"); - } else { - if (sharing == 1) { - DEBUG_CONT("enabled for only read-only segments\n"); - } else { - DEBUG_CONT("disabled\n"); - } - } - - /* Either share all segments or share only read-only segments */ - if ((sharing == 2) || ((sharing == 1) && - !(htlb_seg_info->prot & PROT_WRITE))) { - /* first, try to share */ - ret = hugetlbfs_shared_file(htlb_seg_info); - if (ret >= 0) - return ret; - /* but, fall through to unlinked files, if sharing fails */ - ret = 2; - DEBUG("Falling back to unlinked files\n"); - } - fd = hugetlbfs_unlinked_fd(); - if (fd < 0) - return -1; - htlb_seg_info->fd = fd; - return ret; -} - - /********************************************************************/ /* Library user visible DIAGNOSES/DEBUGGING ONLY functions */ /********************************************************************/ Index: libhugetlbfs/libhugetlbfs_internal.h =================================================================== --- libhugetlbfs.orig/libhugetlbfs_internal.h 2006-09-04 17:08:33.000000000 +1000 +++ libhugetlbfs/libhugetlbfs_internal.h 2006-10-13 16:08:56.000000000 +1000 @@ -48,16 +48,6 @@ extern int sharing; if (__hugetlbfs_verbose >= 3) \ fprintf(stderr, __VA_ARGS__) -struct seg_info { - void *vaddr; - unsigned long filesz, memsz; - int prot; - int fd; -}; - -int finished_prepare(struct seg_info *htlb_seg_info, int success); -int hugetlbfs_set_fd(struct seg_info *htlb_seg_info); - #if defined(__powerpc64__) && !defined(__LP64__) /* Older binutils fail to provide this symbol */ #define __LP64__ -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Libhugetlbfs-devel mailing list Libhugetlbfs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel