1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
/*
* 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$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "ompi_config.h"
#include "sharedfp_lockedfile.h"
#include "mpi.h"
#include "ompi/constants.h"
#include "ompi/mca/sharedfp/sharedfp.h"
#include "ompi/mca/sharedfp/base/base.h"
#include "opal/util/output.h"
#include "opal/util/fd.h"
/*Use fcntl to lock the hidden file which stores the current position*/
#include <fcntl.h>
#include <unistd.h>
int mca_sharedfp_lockedfile_request_position(struct mca_sharedfp_base_data_t * sh,
int bytes_requested,
OMPI_MPI_OFFSET_TYPE *offset)
{
int ret = OMPI_SUCCESS;
/*file descriptor for the hidden file that we want to lock*/
int fd;
/* flock structure that is used to setup the desired fcntl operation */
struct flock fl;
OMPI_MPI_OFFSET_TYPE position = 0;
/*buffer to use when reading from the locked file*/
OMPI_MPI_OFFSET_TYPE buf;
/*int count = 1;*/
struct mca_sharedfp_lockedfile_data * lockedfile_data = sh->selected_module_data;
int handle = lockedfile_data->handle;
*offset = 0;
/* get the saved file descriptor,
* the hidden file was opened during sharedfp_lockedfile_file_open function */
fd = handle;
/*set up the flock structure*/
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = getpid();
/* Acquire an exclusive lock */
if (fcntl(fd, F_SETLKW, &fl) == -1) {
opal_output(0,"sharedfp_lockedfile_request_position: error acquiring lock: fcntl(%d,F_SETLKW,&fl)\n",fd);
opal_output(0,"sharedfp_lockedfile_request_position: error(%i): %s", errno, strerror(errno));
return OMPI_ERROR;
}
else{
if ( mca_sharedfp_lockedfile_verbose ) {
opal_output(ompi_sharedfp_base_framework.framework_output,
"sharedfp_lockedfile_request_position: Success: acquired lock.for fd: %d\n",fd);
}
}
/* read from the file */
lseek ( fd, 0, SEEK_SET );
ret = opal_fd_read ( fd, sizeof(OMPI_MPI_OFFSET_TYPE), &buf);
if (OPAL_SUCCESS != ret ) {
goto exit;
}
if ( mca_sharedfp_lockedfile_verbose ) {
opal_output(ompi_sharedfp_base_framework.framework_output,
"sharedfp_lockedfile_request_position: Read last_offset=%lld! ret=%d\n",buf, ret);
}
/* increment the position */
position = buf + bytes_requested;
if ( mca_sharedfp_lockedfile_verbose ) {
opal_output(ompi_sharedfp_base_framework.framework_output,
"sharedfp_lockedfile_request_position: old_offset=%lld, bytes_requested=%d, new offset=%lld!\n",
buf,bytes_requested,position);
}
/* write to the file */
lseek ( fd, 0, SEEK_SET );
ret = opal_best_effort_write ( fd, &position, sizeof(OMPI_MPI_OFFSET_TYPE));
/* No need to handle error case here, the subsequent steps are identical
in case of ret != OPAL_SUCCESS, namely release lock and return ret */
exit:
/* unlock the file */
if ( mca_sharedfp_lockedfile_verbose ) {
opal_output(ompi_sharedfp_base_framework.framework_output,
"sharedfp_lockedfile_request_position: Releasing lock...");
}
/* NOTE: We thought we could reuse the flock struct
** and only reset the l_type parameter, but it gave
** an invalid argument error. On my machine the invalid
** argument was l_whence. I reset it, but I also decided to
** reset all of the other parameters to avoid further problems.
*/
fl.l_type = F_UNLCK; /* set to unlock same region */
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = getpid();
if (fcntl(fd, F_SETLK, &fl) == -1) {
opal_output(0,"sharedfp_lockedfile_request_position:failed to release lock for fd: %d\n",fd);
opal_output(0,"error(%i): %s", errno, strerror(errno));
/* Only overwrite error code if it was OPAL_SUCCESS previously */
if (OPAL_SUCCESS == ret ) {
ret = OMPI_ERROR;
}
}
else {
if ( mca_sharedfp_lockedfile_verbose ) {
opal_output(ompi_sharedfp_base_framework.framework_output,
"sharedfp_lockedfile_request_position: released lock.for fd: %d\n",fd);
}
}
/* return position */
*offset = buf;
return ret;
}
|