A new flag called _ODP_ISHM_LINK is added to _ishm. When this flag is
specified at reserve() time, a link ("/tmp/odp-<pid>-shm-<blockname>"
where <pid> is the process ID of the main ODP instatiation process and
<blockname> is the block name given at reserve time) is created, linking
to the underlying block file (either in /tmp or in hugetlbfs).
This link is meant to be used by processes external to ODP willing to
share this memory.

Signed-off-by: Christophe Milard <christophe.mil...@linaro.org>
---
 platform/linux-generic/_ishm.c                  | 35 +++++++++++++++++++++++--
 platform/linux-generic/include/_ishm_internal.h |  1 +
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/platform/linux-generic/_ishm.c b/platform/linux-generic/_ishm.c
index f4aa6d3..e6ceb24 100644
--- a/platform/linux-generic/_ishm.c
+++ b/platform/linux-generic/_ishm.c
@@ -99,6 +99,14 @@
 #define ISHM_FILENAME_NORMAL_PAGE_DIR "/tmp"
 
 /*
+ * when the memory is to be shared with an external entity (such as another
+ * ODP instance or an OS process not part of this ODP instance) then a
+ * link is created to the underlying filename: this defines the location
+ * and the format of this link name
+ */
+#define ISHM_LINKNAME_FORMAT "/tmp/odp-%d-shm-%s"
+
+/*
  * At worse case the virtual space gets so fragmented that there is
  * a unallocated fragment between each allocated fragment:
  * In that case, the number of fragments to take care of is twice the
@@ -136,6 +144,7 @@ typedef struct ishm_fragment {
 typedef struct ishm_block {
        char name[ISHM_NAME_MAXLEN];    /* name for the ishm block (if any) */
        char filename[ISHM_FILENAME_MAXLEN]; /* name of the .../odp-* file  */
+       char linkname[ISHM_FILENAME_MAXLEN]; /* name of the /tmp/odp-* link */
        int  main_odpthread;     /* The thread which did the initial reserve*/
        uint32_t user_flags;     /* any flags the user want to remember.    */
        uint32_t flags;          /* block creation flags.                   */
@@ -380,7 +389,7 @@ static void free_fragment(ishm_fragment_t *fragmnt)
  * or /mnt/huge/odp-<pid>-<sequence_or_name> (for huge pages)
  * Return the new file descriptor, or -1 on error.
  */
-static int create_file(int block_index, int huge, uint64_t len)
+static int create_file(int block_index, int huge, uint64_t len, uint32_t flags)
 {
        char *name;
        int  fd;
@@ -429,6 +438,21 @@ static int create_file(int block_index, int huge, uint64_t 
len)
 
        strncpy(new_block->filename, filename, ISHM_FILENAME_MAXLEN - 1);
 
+       /* if _ODP_ISHM_LINK is set, create a symbolic link for external ref: */
+       if (flags & _ODP_ISHM_LINK) {
+               snprintf(new_block->linkname, ISHM_FILENAME_MAXLEN,
+                        ISHM_LINKNAME_FORMAT,
+                        odp_global_data.main_pid,
+                        (name && name[0]) ? name : seq_string);
+               if (symlink(filename, new_block->linkname) < 0) {
+                       ODP_ERR("symlink failed: err=%s.\n",
+                               strerror(errno));
+                       new_block->linkname[0] = 0;
+               }
+       } else {
+               new_block->linkname[0] = 0;
+       }
+
        return fd;
 }
 
@@ -456,7 +480,7 @@ static void *do_map(int block_index, uint64_t len, uint32_t 
align,
         * unless a fd was already given
         */
        if (*fd < 0) {
-               *fd = create_file(block_index, huge, len);
+               *fd = create_file(block_index, huge, len, flags);
                if (*fd < 0)
                        return NULL;
        } else {
@@ -472,6 +496,8 @@ static void *do_map(int block_index, uint64_t len, uint32_t 
align,
                                close(*fd);
                                *fd = -1;
                                unlink(new_block->filename);
+                               if (new_block->linkname[0])
+                                       unlink(new_block->linkname);
                        }
                        return NULL;
                }
@@ -487,6 +513,8 @@ static void *do_map(int block_index, uint64_t len, uint32_t 
align,
                        close(*fd);
                        *fd = -1;
                        unlink(new_block->filename);
+                       if (new_block->linkname[0])
+                               unlink(new_block->linkname);
                }
                return NULL;
        }
@@ -870,6 +898,9 @@ static int block_free(int block_index)
        /* remove the .../odp-* file, unless fd was external: */
        if (block->filename[0] != 0)
                unlink(block->filename);
+       /* also remove possible link: */
+       if (block->linkname[0] != 0)
+               unlink(block->linkname);
 
        /* deregister the file descriptor from the file descriptor server. */
        _odp_fdserver_deregister_fd(FD_SRV_CTX_ISHM, block_index);
diff --git a/platform/linux-generic/include/_ishm_internal.h 
b/platform/linux-generic/include/_ishm_internal.h
index 3231b60..4fa6d9c 100644
--- a/platform/linux-generic/include/_ishm_internal.h
+++ b/platform/linux-generic/include/_ishm_internal.h
@@ -14,6 +14,7 @@ extern "C" {
 /* flags available at ishm_reserve: */
 #define _ODP_ISHM_SINGLE_VA            1
 #define _ODP_ISHM_LOCK                 2
+#define _ODP_ISHM_LINK                 4 /*create soft link in /tmp */
 
 /**
  * Shared memory block info
-- 
2.7.4

Reply via email to