root/opal/mca/pmix/pmix4x/pmix/src/mca/common/dstore/dstore_segment.c

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

DEFINITIONS

This source file includes following definitions.
  1. pmix_common_dstor_getpagesize
  2. pmix_common_dstor_getcacheblocksize
  3. pmix_common_dstor_init_segment_info
  4. pmix_common_dstor_create_new_lock_seg
  5. pmix_common_dstor_attach_new_lock_seg
  6. pmix_common_dstor_create_new_segment
  7. pmix_common_dstor_attach_new_segment
  8. pmix_common_dstor_extend_segment
  9. pmix_common_dstor_delete_sm_desc

   1 /*
   2  * Copyright (c) 2015-2018 Intel, Inc. All rights reserved.
   3  * Copyright (c) 2016      IBM Corporation.  All rights reserved.
   4  * Copyright (c) 2016-2017 Mellanox Technologies, Inc.
   5  *                         All rights reserved.
   6  * Copyright (c) 2018-2019 Research Organization for Information Science
   7  *                         and Technology (RIST).  All rights reserved.
   8  *
   9  * $COPYRIGHT$
  10  *
  11  * Additional copyrights may follow
  12  *
  13  * $HEADER$
  14  */
  15 
  16 #include <src/include/pmix_config.h>
  17 
  18 #ifdef HAVE_UNISTD_H
  19 #include <unistd.h>
  20 #endif
  21 #ifdef HAVE_SYS_TYPES_H
  22 #include <sys/types.h>
  23 #endif
  24 #ifdef HAVE_SYS_STAT_H
  25 #include <sys/stat.h>
  26 #endif
  27 #ifdef HAVE_FCNTL_H
  28 #include <fcntl.h>
  29 #endif
  30 
  31 #ifdef HAVE_SYS_AUXV_H
  32 #include <sys/auxv.h>
  33 #if PMIX_HAVE_LIBEV
  34 /* EV_NONE is macro-defined in <elf.h> that is included by <sys/auxv.h>
  35  * and used in an enum in <event.h> from libev, so #undef it to fix an issue*/
  36 #undef EV_NONE
  37 #endif
  38 #endif
  39 
  40 #include <pmix_common.h>
  41 
  42 #include "src/include/pmix_globals.h"
  43 #include "src/mca/gds/base/base.h"
  44 #include "src/mca/pshmem/base/base.h"
  45 #include "src/util/error.h"
  46 #include "src/util/output.h"
  47 
  48 #include "dstore_common.h"
  49 #include "dstore_segment.h"
  50 
  51 static size_t _initial_segment_size;
  52 static size_t _meta_segment_size;
  53 static size_t _data_segment_size;
  54 
  55 PMIX_EXPORT int pmix_common_dstor_getpagesize(void)
  56 {
  57 #if defined(_SC_PAGESIZE )
  58     return sysconf(_SC_PAGESIZE);
  59 #elif defined(_SC_PAGE_SIZE)
  60     return sysconf(_SC_PAGE_SIZE);
  61 #else
  62     return 65536; /* safer to overestimate than under */
  63 #endif
  64 }
  65 
  66 PMIX_EXPORT size_t pmix_common_dstor_getcacheblocksize(void)
  67 {
  68     size_t cache_line = 0;
  69 
  70 #if defined(_SC_LEVEL1_DCACHE_LINESIZE)
  71     cache_line = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
  72 #endif
  73 #if (defined(HAVE_SYS_AUXV_H)) && (defined(AT_DCACHEBSIZE))
  74     if (0 == cache_line) {
  75         cache_line = getauxval(AT_DCACHEBSIZE);
  76     }
  77 #endif
  78     return cache_line;
  79 }
  80 
  81 PMIX_EXPORT void pmix_common_dstor_init_segment_info(size_t initial_segment_size,
  82                                     size_t meta_segment_size,
  83                                     size_t data_segment_size)
  84 {
  85     _initial_segment_size = initial_segment_size;
  86     _meta_segment_size = meta_segment_size;
  87     _data_segment_size = data_segment_size;
  88 }
  89 
  90 PMIX_EXPORT pmix_dstore_seg_desc_t *pmix_common_dstor_create_new_lock_seg(const char *base_path, size_t size,
  91                                                  const char *name, uint32_t id, uid_t uid, bool setuid)
  92 {
  93     pmix_status_t rc;
  94     char file_name[PMIX_PATH_MAX];
  95     pmix_dstore_seg_desc_t *new_seg = NULL;
  96 
  97     PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output,
  98                          "%s:%d:%s: segment type %d, nspace %s, id %u",
  99                          __FILE__, __LINE__, __func__, PMIX_DSTORE_NS_LOCK_SEGMENT,
 100                          name, id));
 101 
 102     snprintf(file_name, PMIX_PATH_MAX, "%s/smlockseg-%s", base_path, name);
 103     new_seg = (pmix_dstore_seg_desc_t*)malloc(sizeof(pmix_dstore_seg_desc_t));
 104     if (new_seg) {
 105             new_seg->id = id;
 106             new_seg->next = NULL;
 107             new_seg->type = PMIX_DSTORE_NS_LOCK_SEGMENT;
 108             rc = pmix_pshmem.segment_create(&new_seg->seg_info, file_name, size);
 109             if (PMIX_SUCCESS != rc) {
 110                 PMIX_ERROR_LOG(rc);
 111                 goto err_exit;
 112             }
 113             memset(new_seg->seg_info.seg_base_addr, 0, size);
 114 
 115             if (setuid > 0){
 116                 rc = PMIX_ERR_PERM;
 117                 if (0 > chown(file_name, (uid_t) uid, (gid_t) -1)){
 118                     PMIX_ERROR_LOG(rc);
 119                     goto err_exit;
 120                 }
 121                 /* set the mode as required */
 122                 if (0 > chmod(file_name, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP )) {
 123                     PMIX_ERROR_LOG(rc);
 124                     goto err_exit;
 125                 }
 126             }
 127         }
 128         return new_seg;
 129 
 130     err_exit:
 131         if( NULL != new_seg ){
 132             free(new_seg);
 133         }
 134         return NULL;
 135 
 136 }
 137 
 138 PMIX_EXPORT pmix_dstore_seg_desc_t *pmix_common_dstor_attach_new_lock_seg(const char *base_path,
 139                                                  size_t size, const char *name, uint32_t id)
 140 {
 141     pmix_status_t rc;
 142     pmix_dstore_seg_desc_t *new_seg = NULL;
 143     new_seg = (pmix_dstore_seg_desc_t*)malloc(sizeof(pmix_dstore_seg_desc_t));
 144     new_seg->id = id;
 145     new_seg->next = NULL;
 146     new_seg->type = PMIX_DSTORE_NS_LOCK_SEGMENT;
 147     new_seg->seg_info.seg_size = size;
 148 
 149     PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output,
 150                          "%s:%d:%s: segment type %d, name %s, id %u",
 151                          __FILE__, __LINE__, __func__, new_seg->type, name, id));
 152 
 153     snprintf(new_seg->seg_info.seg_name, PMIX_PATH_MAX, "%s/smlockseg-%s",
 154              base_path, name);
 155     rc = pmix_pshmem.segment_attach(&new_seg->seg_info, PMIX_PSHMEM_RW);
 156     if (PMIX_SUCCESS != rc) {
 157         free(new_seg);
 158         new_seg = NULL;
 159     }
 160     return new_seg;
 161 }
 162 
 163 PMIX_EXPORT pmix_dstore_seg_desc_t *pmix_common_dstor_create_new_segment(pmix_dstore_segment_type type,
 164                         const char *base_path, const char *name, uint32_t id,
 165                         uid_t uid, bool setuid)
 166 {
 167     pmix_status_t rc;
 168     char file_name[PMIX_PATH_MAX];
 169     size_t size;
 170     pmix_dstore_seg_desc_t *new_seg = NULL;
 171 
 172     PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output,
 173                          "%s:%d:%s: segment type %d, nspace %s, id %u",
 174                          __FILE__, __LINE__, __func__, type, name, id));
 175 
 176     switch (type) {
 177         case PMIX_DSTORE_INITIAL_SEGMENT:
 178             size = _initial_segment_size;
 179             snprintf(file_name, PMIX_PATH_MAX, "%s/initial-pmix_shared-segment-%u",
 180                 base_path, id);
 181             break;
 182         case PMIX_DSTORE_NS_META_SEGMENT:
 183             size = _meta_segment_size;
 184             snprintf(file_name, PMIX_PATH_MAX, "%s/smseg-%s-%u", base_path, name, id);
 185             break;
 186         case PMIX_DSTORE_NS_DATA_SEGMENT:
 187             size = _data_segment_size;
 188             snprintf(file_name, PMIX_PATH_MAX, "%s/smdataseg-%s-%d", base_path, name, id);
 189             break;
 190         default:
 191             PMIX_ERROR_LOG(PMIX_ERROR);
 192             return NULL;
 193     }
 194     new_seg = (pmix_dstore_seg_desc_t*)malloc(sizeof(pmix_dstore_seg_desc_t));
 195     if (new_seg) {
 196         new_seg->id = id;
 197         new_seg->next = NULL;
 198         new_seg->type = type;
 199         rc = pmix_pshmem.segment_create(&new_seg->seg_info, file_name, size);
 200         if (PMIX_SUCCESS != rc) {
 201             PMIX_ERROR_LOG(rc);
 202             goto err_exit;
 203         }
 204         memset(new_seg->seg_info.seg_base_addr, 0, size);
 205 
 206         if (setuid > 0){
 207             rc = PMIX_ERR_PERM;
 208             if (0 > chown(file_name, (uid_t) uid, (gid_t) -1)){
 209                 PMIX_ERROR_LOG(rc);
 210                 goto err_exit;
 211             }
 212             /* set the mode as required */
 213             if (0 > chmod(file_name, S_IRUSR | S_IRGRP | S_IWGRP )) {
 214                 PMIX_ERROR_LOG(rc);
 215                 goto err_exit;
 216             }
 217         }
 218     }
 219     return new_seg;
 220 
 221 err_exit:
 222     if( NULL != new_seg ){
 223         free(new_seg);
 224     }
 225     return NULL;
 226 }
 227 
 228 PMIX_EXPORT pmix_dstore_seg_desc_t *pmix_common_dstor_attach_new_segment(pmix_dstore_segment_type type, const char *base_path,
 229                                                  const char *name, uint32_t id)
 230 {
 231     pmix_status_t rc;
 232     pmix_dstore_seg_desc_t *new_seg = NULL;
 233     new_seg = (pmix_dstore_seg_desc_t*)malloc(sizeof(pmix_dstore_seg_desc_t));
 234     new_seg->id = id;
 235     new_seg->next = NULL;
 236     new_seg->type = type;
 237 
 238     PMIX_OUTPUT_VERBOSE((10, pmix_gds_base_framework.framework_output,
 239                          "%s:%d:%s: segment type %d, nspace %s, id %u",
 240                          __FILE__, __LINE__, __func__, type, name, id));
 241 
 242     switch (type) {
 243         case PMIX_DSTORE_INITIAL_SEGMENT:
 244             new_seg->seg_info.seg_size = _initial_segment_size;
 245             snprintf(new_seg->seg_info.seg_name, PMIX_PATH_MAX, "%s/initial-pmix_shared-segment-%u",
 246                 base_path, id);
 247             break;
 248         case PMIX_DSTORE_NS_META_SEGMENT:
 249             new_seg->seg_info.seg_size = _meta_segment_size;
 250             snprintf(new_seg->seg_info.seg_name, PMIX_PATH_MAX, "%s/smseg-%s-%u",
 251                 base_path, name, id);
 252             break;
 253         case PMIX_DSTORE_NS_DATA_SEGMENT:
 254             new_seg->seg_info.seg_size = _data_segment_size;
 255             snprintf(new_seg->seg_info.seg_name, PMIX_PATH_MAX, "%s/smdataseg-%s-%d",
 256                 base_path, name, id);
 257             break;
 258         default:
 259             free(new_seg);
 260             PMIX_ERROR_LOG(PMIX_ERROR);
 261             return NULL;
 262     }
 263     rc = pmix_pshmem.segment_attach(&new_seg->seg_info, PMIX_PSHMEM_RONLY);
 264     if (PMIX_SUCCESS != rc) {
 265         free(new_seg);
 266         new_seg = NULL;
 267         PMIX_ERROR_LOG(rc);
 268     }
 269     return new_seg;
 270 }
 271 
 272 PMIX_EXPORT pmix_dstore_seg_desc_t *pmix_common_dstor_extend_segment(pmix_dstore_seg_desc_t *segdesc, const char *base_path,
 273                                              const char *name, uid_t uid, bool setuid)
 274 {
 275     pmix_dstore_seg_desc_t *tmp, *seg;
 276 
 277     PMIX_OUTPUT_VERBOSE((2, pmix_gds_base_framework.framework_output,
 278                          "%s:%d:%s",
 279                          __FILE__, __LINE__, __func__));
 280     /* find last segment */
 281     tmp = segdesc;
 282     while (NULL != tmp->next) {
 283         tmp = tmp->next;
 284     }
 285     /* create another segment, the old one is full. */
 286     seg = pmix_common_dstor_create_new_segment(segdesc->type, base_path, name, tmp->id + 1, uid, setuid);
 287     tmp->next = seg;
 288 
 289     return seg;
 290 }
 291 
 292 PMIX_EXPORT void pmix_common_dstor_delete_sm_desc(pmix_dstore_seg_desc_t *desc)
 293 {
 294     pmix_dstore_seg_desc_t *tmp;
 295 
 296     /* free all global segments */
 297     while (NULL != desc) {
 298         tmp = desc->next;
 299         /* detach & unlink from current desc */
 300         if (desc->seg_info.seg_cpid == getpid()) {
 301             pmix_pshmem.segment_unlink(&desc->seg_info);
 302         }
 303         pmix_pshmem.segment_detach(&desc->seg_info);
 304         free(desc);
 305         desc = tmp;
 306     }
 307 }

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