root/opal/mca/pmix/pmix4x/pmix/src/mca/pshmem/mmap/pshmem_mmap.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _mmap_init
  2. _mmap_finalize
  3. _mmap_segment_create
  4. _mmap_segment_attach
  5. _mmap_segment_detach
  6. _mmap_segment_unlink

   1 /*
   2  * Copyright (c) 2015-2016 Mellanox Technologies, Inc.
   3  *                         All rights reserved.
   4  * Copyright (c) 2017      Research Organization for Information Science
   5  *                         and Technology (RIST). All rights reserved.
   6  * Copyright (c) 2017-2018 Intel, Inc.  All rights reserved.
   7  * $COPYRIGHT$
   8  *
   9  * Additional copyrights may follow
  10  *
  11  * $HEADER$
  12  */
  13 
  14 
  15 #include <unistd.h>
  16 #ifdef HAVE_SYS_TYPES_H
  17 #include <sys/types.h>
  18 #endif
  19 #include <sys/mman.h>
  20 #include <sys/stat.h>
  21 #include <fcntl.h>
  22 #include <errno.h>
  23 
  24 #include <src/include/pmix_config.h>
  25 #include <pmix_common.h>
  26 #include "src/include/pmix_globals.h"
  27 
  28 //#include "pmix_sm.h"
  29 #include <src/mca/pshmem/pshmem.h>
  30 #include "pshmem_mmap.h"
  31 
  32 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
  33 #    define MAP_ANONYMOUS MAP_ANON
  34 #endif /* MAP_ANONYMOUS and MAP_ANON */
  35 
  36 static int _mmap_init(void);
  37 static void _mmap_finalize(void);
  38 static int _mmap_segment_create(pmix_pshmem_seg_t *sm_seg, const char *file_name, size_t size);
  39 static int _mmap_segment_attach(pmix_pshmem_seg_t *sm_seg, pmix_pshmem_access_mode_t sm_mode);
  40 static int _mmap_segment_detach(pmix_pshmem_seg_t *sm_seg);
  41 static int _mmap_segment_unlink(pmix_pshmem_seg_t *sm_seg);
  42 
  43 pmix_pshmem_base_module_t pmix_mmap_module = {
  44     "mmap",
  45     _mmap_init,
  46     _mmap_finalize,
  47     _mmap_segment_create,
  48     _mmap_segment_attach,
  49     _mmap_segment_detach,
  50     _mmap_segment_unlink
  51 };
  52 
  53 static int _mmap_init(void)
  54 {
  55     return PMIX_SUCCESS;
  56 }
  57 
  58 static void _mmap_finalize(void)
  59 {
  60     ;
  61 }
  62 
  63 static int _mmap_segment_create(pmix_pshmem_seg_t *sm_seg, const char *file_name, size_t size)
  64 {
  65     int rc = PMIX_SUCCESS;
  66     void *seg_addr = MAP_FAILED;
  67     pid_t my_pid = getpid();
  68 
  69     _segment_ds_reset(sm_seg);
  70     /* enough space is available, so create the segment */
  71     if (-1 == (sm_seg->seg_id = open(file_name, O_CREAT | O_RDWR, 0600))) {
  72         pmix_output_verbose(2, pmix_globals.debug_output,
  73                 "sys call open(2) fail\n");
  74         rc = PMIX_ERROR;
  75         goto out;
  76     }
  77     /* size backing file - note the use of real_size here */
  78 #ifdef HAVE_POSIX_FALLOCATE
  79     if (0 != (rc = posix_fallocate(sm_seg->seg_id, 0, size))) {
  80         pmix_output_verbose(2, pmix_globals.debug_output,
  81                 "sys call posix_fallocate(2) fail\n");
  82         if (ENOSPC == rc) {
  83             rc = PMIX_ERR_OUT_OF_RESOURCE;
  84             goto out;
  85         } else if ((ENOTSUP != rc)
  86 #ifdef EOPNOTSUPP
  87                             && (EOPNOTSUPP != rc)
  88 #endif
  89         ){
  90             rc = PMIX_ERROR;
  91             goto out;
  92         }
  93         /* else:
  94          * Not supported by OS and/or filesystem.
  95          * Must fall-back to ftruncate().
  96          */
  97     } else {
  98         goto map_memory;
  99     }
 100 #endif
 101     if (0 != ftruncate(sm_seg->seg_id, size)) {
 102         pmix_output_verbose(2, pmix_globals.debug_output,
 103                 "sys call ftruncate(2) fail\n");
 104         rc = PMIX_ERROR;
 105         goto out;
 106     } else {
 107         rc = PMIX_SUCCESS;
 108     }
 109 
 110 #ifdef HAVE_POSIX_FALLOCATE
 111   map_memory:
 112 #endif
 113     if (MAP_FAILED == (seg_addr = mmap(NULL, size,
 114                                        PROT_READ | PROT_WRITE, MAP_SHARED,
 115                                        sm_seg->seg_id, 0))) {
 116         pmix_output_verbose(2, pmix_globals.debug_output,
 117                 "sys call mmap(2) fail\n");
 118         rc = PMIX_ERROR;
 119         goto out;
 120     }
 121     sm_seg->seg_cpid = my_pid;
 122     sm_seg->seg_size = size;
 123     sm_seg->seg_base_addr = (unsigned char *)seg_addr;
 124     pmix_strncpy(sm_seg->seg_name, file_name, PMIX_PATH_MAX);
 125 
 126 out:
 127     if (-1 != sm_seg->seg_id) {
 128         if (0 != close(sm_seg->seg_id)) {
 129             pmix_output_verbose(2, pmix_globals.debug_output,
 130                     "sys call close(2) fail\n");
 131             rc = PMIX_ERROR;
 132          }
 133      }
 134     /* an error occured, so invalidate the shmem object and munmap if needed */
 135     if (PMIX_SUCCESS != rc) {
 136         if (MAP_FAILED != seg_addr) {
 137             munmap((void *)seg_addr, size);
 138         }
 139         _segment_ds_reset(sm_seg);
 140     }
 141     return rc;
 142 }
 143 
 144 static int _mmap_segment_attach(pmix_pshmem_seg_t *sm_seg, pmix_pshmem_access_mode_t sm_mode)
 145 {
 146     mode_t mode = O_RDWR;
 147     int mmap_prot = PROT_READ | PROT_WRITE;
 148 
 149     if (sm_mode == PMIX_PSHMEM_RONLY) {
 150         mode = O_RDONLY;
 151         mmap_prot = PROT_READ;
 152     }
 153 
 154     if (-1 == (sm_seg->seg_id = open(sm_seg->seg_name, mode))) {
 155         return PMIX_ERROR;
 156     }
 157     if (MAP_FAILED == (sm_seg->seg_base_addr = (unsigned char *)
 158                 mmap(NULL, sm_seg->seg_size,
 159                     mmap_prot, MAP_SHARED,
 160                     sm_seg->seg_id, 0))) {
 161         /* mmap failed, so close the file and return NULL - no error check
 162          * here because we are already in an error path...
 163          */
 164         pmix_output_verbose(2, pmix_globals.debug_output,
 165                 "sys call mmap(2) fail\n");
 166         close(sm_seg->seg_id);
 167         return PMIX_ERROR;
 168     }
 169     /* all is well */
 170     /* if close fails here, that's okay.  just let the user know and
 171      * continue.  if we got this far, open and mmap were successful...
 172      */
 173     if (0 != close(sm_seg->seg_id)) {
 174         pmix_output_verbose(2, pmix_globals.debug_output,
 175                 "sys call close(2) fail\n");
 176     }
 177     sm_seg->seg_cpid = 0;/* FIXME */
 178     return PMIX_SUCCESS;
 179 }
 180 
 181 static int _mmap_segment_detach(pmix_pshmem_seg_t *sm_seg)
 182 {
 183     int rc = PMIX_SUCCESS;
 184 
 185     if (0 != munmap((void *)sm_seg->seg_base_addr, sm_seg->seg_size)) {
 186         pmix_output_verbose(2, pmix_globals.debug_output,
 187                 "sys call munmap(2) fail\n");
 188         rc = PMIX_ERROR;
 189     }
 190     /* reset the contents of the pmix_sm_seg_t associated with this
 191      * shared memory segment.
 192      */
 193     _segment_ds_reset(sm_seg);
 194     return rc;
 195 }
 196 
 197 static int _mmap_segment_unlink(pmix_pshmem_seg_t *sm_seg)
 198 {
 199     if (-1 == unlink(sm_seg->seg_name)) {
 200         pmix_output_verbose(2, pmix_globals.debug_output,
 201                 "sys call unlink(2) fail\n");
 202         return PMIX_ERROR;
 203     }
 204 
 205     sm_seg->seg_id = PMIX_SHMEM_DS_ID_INVALID;
 206     return PMIX_SUCCESS;
 207 }

/* [<][>][^][v][top][bottom][index][help] */