int mca_fs_base_get_fstype(char *fname ) { int ompio_type = UFS; char *fstype=NULL; bool ret = opal_path_nfs ( fname, &fstype ); if ( false == ret ) { char *dir; mca_fs_base_get_parent_dir (fname, &dir ); ret = opal_path_nfs (dir, &fstype); free(dir); if ( false == ret ) { return ompio_type; } } if ( 0 == strncasecmp(fstype, "lustre", sizeof("lustre")) ) { ompio_type = LUSTRE; } else if ( 0 == strncasecmp(fstype, "pvfs2", sizeof("pvfs2"))) { ompio_type = PVFS2; } else if ( 0 == strncasecmp(fstype, "ime", sizeof("ime"))) { ompio_type = IME; } free (fstype); return ompio_type; }
int main(int argc, char* argv[]) { int num_dirs; char ** dirs; bool * nfs; test_init("opal_path_nfs()"); #ifdef DEBUG printf ("Test usage: ./opal_path_nfs [DIR]\n"); printf ("On Linux interprets output from mount(8) to check for nfs and verify opal_path_nfs()\n"); printf ("Additionally, you may specify multiple DIR on the cmd-line, of which you the output\n"); #endif if (1 < argc) { int i; for (i = 1; i < argc; i++) printf ("Is dir[%d]:%s one of the detected network file systems? %s\n", i, argv[i], opal_path_nfs (argv[i], NULL) ? "Yes": "No"); } get_mounts (&num_dirs, &dirs, &nfs); while (num_dirs--) { test (dirs[num_dirs], nfs[num_dirs]); } /* All done */ return test_finalize(); }
void test(char* file, bool expect) { #ifdef DEBUG printf ("test(): file:%s bool:%d\n", file, expect); #endif if (expect == opal_path_nfs (file, NULL)) { test_success(); } else { char * msg; opal_asprintf(&msg, "Mismatch: input \"%s\", expected:%d got:%d\n", file, expect, !expect); test_failure(msg); free(msg); } }
int main(int argc, char* argv[]) { if (argc > 1) { int i; printf("Interactive opal_path_nfs() test:\n"); for (i = 1; i < argc; i++) { printf ("Is dir[%d]:%s one of the detected network file systems? %s\n", i, argv[i], opal_path_nfs (argv[i], NULL) ? "Yes": "No"); } return 0; } printf("No filename was given; nothing to do\n"); return 77; }
/* ////////////////////////////////////////////////////////////////////////// */ static int segment_create(opal_shmem_ds_t *ds_buf, const char *file_name, size_t size) { int rc = OPAL_SUCCESS; char *real_file_name = NULL; pid_t my_pid = getpid(); bool space_available = false; uint64_t amount_space_avail = 0; /* the real size of the shared memory segment. this includes enough space * to store our segment header. */ size_t real_size = size + sizeof(opal_shmem_seg_hdr_t); opal_shmem_seg_hdr_t *seg_hdrp = MAP_FAILED; /* init the contents of opal_shmem_ds_t */ shmem_ds_reset(ds_buf); /* change the path of shmem mmap's backing store? */ if (0 != opal_shmem_mmap_relocate_backing_file) { int err; if (path_usable(opal_shmem_mmap_backing_file_base_dir, &err)) { if (NULL == (real_file_name = get_uniq_file_name(opal_shmem_mmap_backing_file_base_dir, file_name))) { /* out of resources */ return OPAL_ERROR; } } /* a relocated backing store was requested, but the path specified * cannot be used :-(. if the flag is negative, then warn and continue * with the default path. otherwise, fail. */ else if (opal_shmem_mmap_relocate_backing_file < 0) { opal_output(0, "shmem: mmap: WARNING: could not relocate " "backing store to \"%s\" (%s). Continuing with " "default path.\n", opal_shmem_mmap_backing_file_base_dir, strerror(err)); } /* must be positive, so fail */ else { opal_output(0, "shmem: mmap: WARNING: could not relocate " "backing store to \"%s\" (%s). Cannot continue with " "shmem mmap.\n", opal_shmem_mmap_backing_file_base_dir, strerror(err)); return OPAL_ERROR; } } /* are we using the default path? */ if (NULL == real_file_name) { /* use the path specified by the caller of this function */ if (NULL == (real_file_name = strdup(file_name))) { /* out of resources */ return OPAL_ERROR; } } OPAL_OUTPUT_VERBOSE( (70, opal_shmem_base_framework.framework_output, "%s: %s: backing store base directory: %s\n", mca_shmem_mmap_component.super.base_version.mca_type_name, mca_shmem_mmap_component.super.base_version.mca_component_name, real_file_name) ); /* determine whether the specified filename is on a network file system. * this is an important check because if the backing store is located on * a network filesystem, the user may see a shared memory performance hit. */ if (opal_shmem_mmap_nfs_warning && opal_path_nfs(real_file_name)) { char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-mmap.txt", "mmap on nfs", 1, hn, real_file_name); } /* let's make sure we have enough space for the backing file */ if (OPAL_SUCCESS != (rc = enough_space(real_file_name, real_size, &amount_space_avail, &space_available))) { opal_output(0, "shmem: mmap: an error occurred while determining " "whether or not %s could be created.", real_file_name); /* rc is set */ goto out; } if (!space_available) { char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; rc = OPAL_ERR_OUT_OF_RESOURCE; opal_show_help("help-opal-shmem-mmap.txt", "target full", 1, real_file_name, hn, (unsigned long)real_size, (unsigned long long)amount_space_avail); goto out; } /* enough space is available, so create the segment */ if (-1 == (ds_buf->seg_id = open(real_file_name, O_CREAT | O_RDWR, 0600))) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-mmap.txt", "sys call fail", 1, hn, "open(2)", "", strerror(err), err); rc = OPAL_ERROR; goto out; } /* size backing file - note the use of real_size here */ if (0 != ftruncate(ds_buf->seg_id, real_size)) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-mmap.txt", "sys call fail", 1, hn, "ftruncate(2)", "", strerror(err), err); rc = OPAL_ERROR; goto out; } if (MAP_FAILED == (seg_hdrp = (opal_shmem_seg_hdr_t *) mmap(NULL, real_size, PROT_READ | PROT_WRITE, MAP_SHARED, ds_buf->seg_id, 0))) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-mmap.txt", "sys call fail", 1, hn, "mmap(2)", "", strerror(err), err); rc = OPAL_ERROR; goto out; } /* all is well */ else { /* -- initialize the shared memory segment -- */ opal_atomic_rmb(); /* init segment lock */ opal_atomic_init(&seg_hdrp->lock, OPAL_ATOMIC_UNLOCKED); /* i was the creator of this segment, so note that fact */ seg_hdrp->cpid = my_pid; opal_atomic_wmb(); /* -- initialize the contents of opal_shmem_ds_t -- */ ds_buf->seg_cpid = my_pid; ds_buf->seg_size = real_size; ds_buf->seg_base_addr = (unsigned char *)seg_hdrp; (void)strncpy(ds_buf->seg_name, real_file_name, OPAL_PATH_MAX - 1); /* set "valid" bit because setment creation was successful */ OPAL_SHMEM_DS_SET_VALID(ds_buf); OPAL_OUTPUT_VERBOSE( (70, opal_shmem_base_framework.framework_output, "%s: %s: create successful " "(id: %d, size: %lu, name: %s)\n", mca_shmem_mmap_component.super.base_version.mca_type_name, mca_shmem_mmap_component.super.base_version.mca_component_name, ds_buf->seg_id, (unsigned long)ds_buf->seg_size, ds_buf->seg_name) ); } out: /* in this component, the id is the file descriptor returned by open. this * check is here to see if it is safe to call close on the file descriptor. * that is, we are making sure that our call to open was successful and * we are not not in an error path. */ if (-1 != ds_buf->seg_id) { if (0 != close(ds_buf->seg_id)) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-mmap.txt", "sys call fail", 1, hn, "close(2)", "", strerror(err), err); rc = OPAL_ERROR; } } /* an error occured, so invalidate the shmem object and munmap if needed */ if (OPAL_SUCCESS != rc) { if (MAP_FAILED != seg_hdrp) { munmap((void *)seg_hdrp, real_size); } shmem_ds_reset(ds_buf); } /* safe to free now because its contents have already been copied */ if (NULL != real_file_name) { free(real_file_name); } return rc; }
/* * file_open_ufs * * Function: - opens a new file * Accepts: - same arguments as MPI_File_open() * Returns: - Success if new file handle */ int mca_fs_ufs_file_open (struct ompi_communicator_t *comm, const char* filename, int access_mode, struct opal_info_t *info, mca_io_ompio_file_t *fh) { int amode; int old_mask, perm; int rank, ret=OMPI_SUCCESS; rank = ompi_comm_rank ( comm ); if (fh->f_perm == OMPIO_PERM_NULL) { old_mask = umask(022); umask(old_mask); perm = old_mask ^ 0666; } else { perm = fh->f_perm; } amode = 0; if (access_mode & MPI_MODE_RDONLY) amode = amode | O_RDONLY; if (access_mode & MPI_MODE_WRONLY) amode = amode | O_WRONLY; if (access_mode & MPI_MODE_RDWR) amode = amode | O_RDWR; /* Reset errno */ errno = 0; if ( 0 == rank ) { /* MODE_CREATE and MODE_EXCL can only be set by one process */ if ( !(fh->f_flags & OMPIO_SHAREDFP_IS_SET)) { if ( access_mode & MPI_MODE_CREATE ) amode = amode | O_CREAT; if (access_mode & MPI_MODE_EXCL) amode = amode | O_EXCL; } fh->fd = open (filename, amode, perm); if ( 0 > fh->fd ) { if ( EACCES == errno ) { ret = MPI_ERR_ACCESS; } else if ( ENAMETOOLONG == errno ) { ret = MPI_ERR_BAD_FILE; } else if ( ENOENT == errno ) { ret = MPI_ERR_NO_SUCH_FILE; } else if ( EISDIR == errno ) { ret = MPI_ERR_BAD_FILE; } else if ( EROFS == errno ) { ret = MPI_ERR_READ_ONLY; } else if ( EEXIST == errno ) { ret = MPI_ERR_FILE_EXISTS; } else if ( ENOSPC == errno ) { ret = MPI_ERR_NO_SPACE; } else if ( EDQUOT == errno ) { ret = MPI_ERR_QUOTA; } else if ( ETXTBSY == errno ) { ret = MPI_ERR_FILE_IN_USE; } else { ret = MPI_ERR_OTHER; } } } comm->c_coll->coll_bcast ( &ret, 1, MPI_INT, 0, comm, comm->c_coll->coll_bcast_module); if ( OMPI_SUCCESS != ret ) { fh->fd = -1; return ret; } if ( 0 != rank ) { fh->fd = open (filename, amode, perm); if ( 0 > fh->fd) { if ( EACCES == errno ) { ret = MPI_ERR_ACCESS; } else if ( ENAMETOOLONG == errno ) { ret = MPI_ERR_BAD_FILE; } else if ( ENOENT == errno ) { ret = MPI_ERR_NO_SUCH_FILE; } else if ( EISDIR == errno ) { ret = MPI_ERR_BAD_FILE; } else if ( EROFS == errno ) { ret = MPI_ERR_READ_ONLY; } else if ( EEXIST == errno ) { ret = MPI_ERR_FILE_EXISTS; } else if ( ENOSPC == errno ) { ret = MPI_ERR_NO_SPACE; } else if ( EDQUOT == errno ) { ret = MPI_ERR_QUOTA; } else if ( ETXTBSY == errno ) { ret = MPI_ERR_FILE_IN_USE; } else { ret = MPI_ERR_OTHER; } } } fh->f_stripe_size=0; fh->f_stripe_count=1; /* Need to check for NFS here. If the file system is not NFS but a regular UFS file system, we do not need to enforce locking. A regular XFS or EXT4 file system can only be used within a single node, local environment, and in this case the OS will already ensure correct handling of file system blocks; */ if ( FS_UFS_LOCK_AUTO == mca_fs_ufs_lock_algorithm ) { char *fstype=NULL; bool bret = opal_path_nfs ( (char *)filename, &fstype ); if ( false == bret ) { char *dir; mca_fs_base_get_parent_dir ( (char *)filename, &dir ); bret = opal_path_nfs (dir, &fstype); free(dir); } if ( true == bret ) { if ( 0 == strncasecmp(fstype, "nfs", sizeof("nfs")) ) { /* Based on my tests, only locking the entire file for all operations guarantueed for the entire teststuite to pass correctly. I would not be surprised, if depending on the NFS configuration that might not always be necessary, and the user can change that with an MCA parameter of this component. */ fh->f_flags |= OMPIO_LOCK_ENTIRE_FILE; } else { fh->f_flags |= OMPIO_LOCK_NEVER; } } else { fh->f_flags |= OMPIO_LOCK_NEVER; } free (fstype); } else if ( FS_UFS_LOCK_NEVER == mca_fs_ufs_lock_algorithm ) { fh->f_flags |= OMPIO_LOCK_NEVER; } else if ( FS_UFS_LOCK_ENTIRE_FILE == mca_fs_ufs_lock_algorithm ) { fh->f_flags |= OMPIO_LOCK_ENTIRE_FILE; } else if ( FS_UFS_LOCK_RANGES == mca_fs_ufs_lock_algorithm ) { /* Nothing to be done. This is what the posix fbtl component would do anyway without additional information . */ } else { opal_output ( 1, "Invalid value for mca_fs_ufs_lock_algorithm %d", mca_fs_ufs_lock_algorithm ); } return OMPI_SUCCESS; }