1
1
openmpi/ompi/mca/sharedfp/sm/sharedfp_sm_file_open.c
2015-06-23 20:59:57 -07:00

266 строки
8.6 KiB
C

/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2013-2015 University of Houston. All rights reserved.
* Copyright (c) 2013 Intel, Inc. All rights reserved.
* Copyright (c) 2015 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "ompi_config.h"
#if HAVE_LIBGEN_H
#include <libgen.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include "sharedfp_sm.h"
#include "mpi.h"
#include "ompi/constants.h"
#include "ompi/mca/sharedfp/sharedfp.h"
#include "ompi/mca/sharedfp/base/base.h"
#include <semaphore.h>
#include <sys/mman.h>
#include <libgen.h>
int mca_sharedfp_sm_file_open (struct ompi_communicator_t *comm,
char* filename,
int amode,
struct ompi_info_t *info,
mca_io_ompio_file_t *fh)
{
int err = OMPI_SUCCESS;
struct mca_sharedfp_base_data_t* sh;
struct mca_sharedfp_sm_data * sm_data = NULL;
mca_io_ompio_file_t * shfileHandle;
char * filename_basename;
char * sm_filename;
struct sm_offset * sm_offset_ptr;
struct sm_offset sm_offset;
int sm_fd;
int rank;
/*----------------------------------------------------*/
/*Open the same file again without shared file pointer*/
/*----------------------------------------------------*/
shfileHandle = (mca_io_ompio_file_t *)malloc(sizeof(mca_io_ompio_file_t));
err = ompio_io_ompio_file_open(comm,filename,amode,info,shfileHandle,false);
if ( OMPI_SUCCESS != err) {
opal_output(0, "mca_sharedfp_sm_file_open: Error during file open\n");
return err;
}
/*Memory is allocated here for the sh structure*/
if ( mca_sharedfp_sm_verbose ) {
printf( "mca_sharedfp_sm_file_open: malloc f_sharedfp_ptr struct\n");
}
sh = (struct mca_sharedfp_base_data_t*)malloc(sizeof(struct mca_sharedfp_base_data_t));
if ( NULL == sh ) {
opal_output(0, "mca_sharedfp_sm_file_open: Error, unable to malloc f_sharedfp_ptr struct\n");
free(shfileHandle);
return OMPI_ERR_OUT_OF_RESOURCE;
}
/*Populate the sh file structure based on the implementation*/
sh->sharedfh = shfileHandle; /* Shared file pointer*/
sh->global_offset = 0; /* Global Offset*/
sh->comm = comm; /* Communicator*/
sh->selected_module_data = NULL;
rank = ompi_comm_rank ( sh->comm );
/*Open a shared memory segment which will hold the shared file pointer*/
if ( mca_sharedfp_sm_verbose ) {
printf( "mca_sharedfp_sm_file_open: allocatge shared memory segment.\n");
}
sm_data = (struct mca_sharedfp_sm_data*) malloc ( sizeof(struct mca_sharedfp_sm_data));
if ( NULL == sm_data ){
opal_output(0, "mca_sharedfp_sm_file_open: Error, unable to malloc sm_data struct\n");
free(sh);
free(shfileHandle);
return OMPI_ERR_OUT_OF_RESOURCE;
}
sm_data->sm_filename=NULL;
/* the shared memory segment is identified opening a file
** and then mapping it to memory
** For sharedfp we also want to put the file backed shared memory into the tmp directory
** TODO: properly name the file so that different jobs can run on the same system w/o
** overwriting each other, e.g. orte_process_info.proc_session_dir
*/
/*sprintf(sm_filename,"%s%s",filename,".sm");*/
filename_basename = basename(filename);
sm_filename = (char*) malloc( sizeof(char) * (strlen(filename_basename)+64) );
if (NULL == sm_filename) {
free(sm_data);
free(sh);
free(shfileHandle);
return OMPI_ERR_OUT_OF_RESOURCE;
}
sprintf(sm_filename,"/tmp/OMPIO_sharedfp_sm_%s%s",filename_basename,".sm");
/* open shared memory file, initialize to 0, map into memory */
sm_fd = open(sm_filename, O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if ( sm_fd == -1){
/*error opening file*/
printf("mca_sharedfp_sm_file_open: Error, unable to open file for mmap: %s\n",sm_filename);
free(sm_filename);
free(sm_data);
free(sh);
free(shfileHandle);
return OMPI_ERROR;
}
free(sm_filename);
sm_data->sm_filename = sm_filename;
/*TODO: is it necessary to write to the file first?*/
if( 0 == rank ){
memset ( &sm_offset, 0, sizeof (struct sm_offset ));
write ( sm_fd, &sm_offset, sizeof(struct sm_offset));
}
comm->c_coll.coll_barrier (comm, comm->c_coll.coll_barrier_module );
/*the file has been written to, now we can map*/
sm_offset_ptr = mmap(NULL, sizeof(struct sm_offset), PROT_READ | PROT_WRITE,
MAP_SHARED, sm_fd, 0);
close(sm_fd);
if ( sm_offset_ptr==MAP_FAILED){
err = OMPI_ERROR;
printf("mca_sharedfp_sm_file_open: Error, unable to mmap file: %s\n",sm_filename);
printf("%s\n", strerror(errno));
free(sm_filename);
free(sm_data);
free(sh);
free(shfileHandle);
return OMPI_ERROR;
}
/* Initialize semaphore so that is shared between processes. */
/* the semaphore is shared by keeping it in the shared memory segment */
#ifdef OMPIO_SHAREDFP_USE_UNNAMED_SEMAPHORES
if(sem_init(&sm_offset_ptr->mutex, 1, 1) != -1){
#else
sm_data->sem_name = (char*) malloc( sizeof(char) * (strlen(filename_basename)+32) );
sprintf(sm_data->sem_name,"OMPIO_sharedfp_sem_%s",filename_basename);
if( (sm_data->mutex = sem_open(sm_data->sem_name, O_CREAT, 0644, 1)) != SEM_FAILED ) {
#endif
/*If opening was successful*/
/*Store the new file handle*/
sm_data->sm_offset_ptr = sm_offset_ptr;
/* Assign the sm_data to sh->selected_module_data*/
sh->selected_module_data = sm_data;
/*remember the shared file handle*/
fh->f_sharedfp_data = sh;
/*write initial zero*/
if(rank==0){
MPI_Offset position=0;
#ifdef OMPIO_SHAREDFP_USE_UNNAMED_SEMAPHORES
sem_wait(sm_offset_ptr->mutex);
sm_offset_ptr->offset=position;
sem_post(sm_offset_ptr->mutex);
#else
sem_wait(sm_data->mutex);
sm_offset_ptr->offset=position;
sem_post(sm_data->mutex);
#endif
}
}else{
free(sm_filename);
free(sm_data);
free(sh);
free(shfileHandle);
munmap(sm_offset_ptr, sizeof(struct sm_offset));
err = OMPI_ERROR;
}
comm->c_coll.coll_barrier (comm, comm->c_coll.coll_barrier_module );
return err;
}
int mca_sharedfp_sm_file_close (mca_io_ompio_file_t *fh)
{
int err = OMPI_SUCCESS;
/*sharedfp data structure*/
struct mca_sharedfp_base_data_t *sh=NULL;
/*sharedfp sm module data structure*/
struct mca_sharedfp_sm_data * file_data=NULL;
if( NULL == fh->f_sharedfp_data ){
if ( mca_sharedfp_sm_verbose ) {
printf("sharedfp_sm_file_close: shared file pointer structure not initialized\n");
}
return OMPI_SUCCESS;
}
sh = fh->f_sharedfp_data;
/* Use an MPI Barrier in order to make sure that
* all processes are ready to release the
* shared file pointer resources
*/
sh->comm->c_coll.coll_barrier (sh->comm, sh->comm->c_coll.coll_barrier_module );
file_data = (sm_data*)(sh->selected_module_data);
if (file_data) {
/*Close sm handle*/
if (file_data->sm_offset_ptr) {
/* destroy semaphore */
#ifdef OMPIO_SHAREDFP_USE_UNNAMED_SEMAPHORES
sem_destroy(file_data->sm_offset_ptr->mutex);
#else
sem_unlink (file_data->sem_name);
free (file_data->sem_name);
#endif
/*Release the shared memory segment.*/
munmap(file_data->sm_offset_ptr,sizeof(struct sm_offset));
/*Q: Do we need to delete the file? */
remove(file_data->sm_filename);
}
/*free our sm data structure*/
if(file_data->sm_filename){
free(file_data->sm_filename);
}
free(file_data);
}
/* Close the main file opened by this component*/
err = ompio_io_ompio_file_close(sh->sharedfh);
/*free shared file pointer data struct*/
free(sh);
return err;
}