static void fake_an_open(PVFS_fs_id id, const char *pvfs2_name, int access_mode, int stripe_width, PVFS_size stripe_size, mca_fs_pvfs2 *pvfs2_fs, open_status *o_status) { int ret; PVFS_sysresp_lookup resp_lookup; PVFS_sysresp_getparent resp_getparent; PVFS_sysresp_create resp_create; PVFS_sys_attr attribs; PVFS_sys_dist *dist; memset(&attribs, 0, sizeof(PVFS_sys_attr)); attribs.owner = geteuid(); attribs.group = getegid(); attribs.perms = 0644; attribs.mask = PVFS_ATTR_SYS_ALL_SETABLE; attribs.atime = time(NULL); attribs.mtime = attribs.atime; attribs.ctime = attribs.atime; if (stripe_width > 0 ) { attribs.dfile_count = stripe_width; attribs.mask |= PVFS_ATTR_SYS_DFILE_COUNT; } dist = NULL; memset(&resp_lookup, 0, sizeof(resp_lookup)); memset(&resp_getparent, 0, sizeof(resp_getparent)); memset(&resp_create, 0, sizeof(resp_create)); ret = PVFS_sys_lookup(id, pvfs2_name, &(pvfs2_fs->credentials), &resp_lookup, PVFS2_LOOKUP_LINK_FOLLOW); if ( ret == (-PVFS_ENOENT)) { if (access_mode & MPI_MODE_CREATE) { ret = PVFS_sys_getparent(id, pvfs2_name, &(pvfs2_fs->credentials), &resp_getparent); if (ret < 0) { opal_output (1, "pvfs_sys_getparent returns with %d\n", ret); o_status->error = ret; return; } /* Set the distribution stripe size if specified */ if (0 < stripe_size) { /* Note that the distribution is hardcoded here */ dist = PVFS_sys_dist_lookup ("simple_stripe"); ret = PVFS_sys_dist_setparam (dist, "strip_size", &stripe_size); if (ret < 0) { opal_output (1, "pvfs_sys_dist_setparam returns with %d\n", ret); o_status->error = ret; } } /* Perform file creation */ ret = PVFS_sys_create(resp_getparent.basename, resp_getparent.parent_ref, attribs, &(pvfs2_fs->credentials), dist, &resp_create); /* #ifdef HAVE_PVFS2_CREATE_WITHOUT_LAYOUT ret = PVFS_sys_create(resp_getparent.basename, resp_getparent.parent_ref, attribs, &(pvfs2_fs->credentials), dist, &resp_create); #else ret = PVFS_sys_create(resp_getparent.basename, resp_getparent.parent_ref, attribs, &(pvfs2_fs->credentials), dist, NULL, &resp_create); #endif */ /* if many creates are happening in this directory, the earlier * sys_lookup may have returned ENOENT, but the sys_create could * return EEXISTS. That means the file has been created anyway, so * less work for us and we can just open it up and return the * handle */ if (ret == (-PVFS_EEXIST)) { ret = PVFS_sys_lookup(id, pvfs2_name, &(pvfs2_fs->credentials), &resp_lookup, PVFS2_LOOKUP_LINK_FOLLOW); if ( ret < 0 ) { o_status->error = ret; return; } o_status->error = ret; o_status->object_ref = resp_lookup.ref; return; } o_status->object_ref = resp_create.ref; } else { opal_output (10, "cannot create file without MPI_MODE_CREATE\n"); o_status->error = ret; return; } } else if (access_mode & MPI_MODE_EXCL) { /* lookup should not succeed if opened with EXCL */ o_status->error = -PVFS_EEXIST; return; } else { o_status->object_ref = resp_lookup.ref; } o_status->error = ret; return; }
int generic_open(file_object *obj, PVFS_credentials *credentials, int nr_datafiles, PVFS_size strip_size, char *srcname, int open_type) { struct stat stat_buf; PVFS_sysresp_lookup resp_lookup; PVFS_sysresp_getattr resp_getattr; PVFS_sysresp_create resp_create; PVFS_object_ref parent_ref; PVFS_sys_dist *new_dist; int ret = -1; char *entry_name; /* name of the pvfs2 file */ char str_buf[PVFS_NAME_MAX]; /* basename of pvfs2 file */ if (obj->fs_type == UNIX_FILE) { memset(&stat_buf, 0, sizeof(struct stat)); stat(obj->u.ufs.path, &stat_buf); if (open_type == OPEN_SRC) { if (S_ISDIR(stat_buf.st_mode)) { fprintf(stderr, "Source cannot be a directory\n"); return(-1); } obj->u.ufs.fd = open(obj->u.ufs.path, O_RDONLY); obj->u.ufs.mode = (int)stat_buf.st_mode; } else { if (S_ISDIR(stat_buf.st_mode)) { if (srcname) { strncat(obj->u.ufs.path, basename(srcname), NAME_MAX); } else { fprintf(stderr, "cannot find name for " "destination. giving up\n"); return(-1); } } obj->u.ufs.fd = open(obj->u.ufs.path, O_WRONLY|O_CREAT|O_LARGEFILE|O_TRUNC,0666); } if (obj->u.ufs.fd < 0) { perror("open"); fprintf(stderr, "could not open %s\n", obj->u.ufs.path); return (-1); } } else { entry_name = str_buf; /* it's a PVFS2 file */ if (strcmp(obj->u.pvfs2.pvfs2_path, "/") == 0) { /* special case: PVFS2 root file system, so stuff the end of * srcfile onto pvfs2_path */ char *segp = NULL, *prev_segp = NULL; void *segstate = NULL; /* can only perform this special case if we know srcname */ if (srcname == NULL) { fprintf(stderr, "unable to guess filename in " "toplevel PVFS2\n"); return -1; } memset(&resp_lookup, 0, sizeof(PVFS_sysresp_lookup)); ret = PVFS_sys_lookup(obj->u.pvfs2.fs_id, obj->u.pvfs2.pvfs2_path, credentials, &resp_lookup, PVFS2_LOOKUP_LINK_FOLLOW, hints); if (ret < 0) { PVFS_perror("PVFS_sys_lookup", ret); return (-1); } parent_ref.handle = resp_lookup.ref.handle; parent_ref.fs_id = resp_lookup.ref.fs_id; while (!PINT_string_next_segment(srcname, &segp, &segstate)) { prev_segp = segp; } entry_name = prev_segp; /* see... points to basename of srcname */ } else /* given either a pvfs2 directory or a pvfs2 file */ { /* get the absolute path on the pvfs2 file system */ /*parent_ref.fs_id = obj->pvfs2.fs_id; */ if (PINT_remove_base_dir(obj->u.pvfs2.pvfs2_path,str_buf, PVFS_NAME_MAX)) { if(obj->u.pvfs2.pvfs2_path[0] != '/') { fprintf(stderr, "Error: poorly formatted path.\n"); } fprintf(stderr, "Error: cannot retrieve entry name for " "creation on %s\n", obj->u.pvfs2.user_path); return(-1); } ret = PINT_lookup_parent(obj->u.pvfs2.pvfs2_path, obj->u.pvfs2.fs_id, credentials, &parent_ref.handle); if (ret < 0) { PVFS_perror("PVFS_util_lookup_parent", ret); return (-1); } else /* parent lookup succeeded. if the pvfs2 path is just a directory, use basename of src for the new file */ { int len = strlen(obj->u.pvfs2.pvfs2_path); if (obj->u.pvfs2.pvfs2_path[len - 1] == '/') { char *segp = NULL, *prev_segp = NULL; void *segstate = NULL; if (srcname == NULL) { fprintf(stderr, "unable to guess filename\n"); return(-1); } while (!PINT_string_next_segment(srcname, &segp, &segstate)) { prev_segp = segp; } strncat(obj->u.pvfs2.pvfs2_path, prev_segp, PVFS_NAME_MAX); entry_name = prev_segp; } parent_ref.fs_id = obj->u.pvfs2.fs_id; } } memset(&resp_lookup, 0, sizeof(PVFS_sysresp_lookup)); ret = PVFS_sys_ref_lookup(parent_ref.fs_id, entry_name, parent_ref, credentials, &resp_lookup, PVFS2_LOOKUP_LINK_FOLLOW, hints); if ((ret == 0) && (open_type == OPEN_SRC)) { memset(&resp_getattr, 0, sizeof(PVFS_sysresp_getattr)); ret = PVFS_sys_getattr(resp_lookup.ref, PVFS_ATTR_SYS_ALL_NOHINT, credentials, &resp_getattr, hints); if (ret) { fprintf(stderr, "Failed to do pvfs2 getattr on %s\n", entry_name); return -1; } if (resp_getattr.attr.objtype == PVFS_TYPE_SYMLINK) { free(resp_getattr.attr.link_target); resp_getattr.attr.link_target = NULL; } obj->u.pvfs2.perms = resp_getattr.attr.perms; memcpy(&obj->u.pvfs2.attr, &resp_getattr.attr, sizeof(PVFS_sys_attr)); obj->u.pvfs2.attr.mask = PVFS_ATTR_SYS_ALL_SETABLE; } /* at this point, we have looked up the file in the parent directory. * . If we found something, and we are the SRC, then we're done. * . We will maintain the semantic of pvfs2-import and refuse to * overwrite existing PVFS2 files, so if we found something, and we * are the DEST, then that's an error. * . Otherwise, we found nothing and we will create the destination. */ if (open_type == OPEN_SRC) { if (ret == 0) { obj->u.pvfs2.ref = resp_lookup.ref; return 0; } else { PVFS_perror("PVFS_sys_ref_lookup", ret); return (ret); } } if (open_type == OPEN_DEST) { if (ret == 0) { obj->u.pvfs2.ref = resp_lookup.ref; return 0; } else { memset(&stat_buf, 0, sizeof(struct stat)); /* preserve permissions doing a unix => pvfs2 copy */ stat(srcname, &stat_buf); make_attribs(&(obj->u.pvfs2.attr), credentials, nr_datafiles, (int)stat_buf.st_mode); if (strip_size > 0) { new_dist = PVFS_sys_dist_lookup("simple_stripe"); ret = PVFS_sys_dist_setparam(new_dist, "strip_size", &strip_size); if (ret < 0) { PVFS_perror("PVFS_sys_dist_setparam", ret); return -1; } } else { new_dist=NULL; } ret = PVFS_sys_create(entry_name, parent_ref, obj->u.pvfs2.attr, credentials, new_dist, &resp_create, NULL, hints); if (ret < 0) { PVFS_perror("PVFS_sys_create", ret); return -1; } obj->u.pvfs2.ref = resp_create.ref; } } } return 0; }
/* steps for getting a handle: (it gets a little convoluted, but at least * it's deterministic) * . lookup the file. * . if lookup succeeds, but we were passed MPI_MODE_EXCL, that's an error * . if lookup fails, the file might not exist. * in that case, create the file if we were passed MPI_MODE_CREATE * . if the create fails, that means someone else created the file between * our call to lookup and our call to create (like if N processors all * open the same file with MPI_COMM_SELF) * * the good news is that only one processor does this and broadcasts the * handle to everyone else in the communicator */ static void fake_an_open(PVFS_fs_id fs_id, char *pvfs_name, int access_mode, int nr_datafiles, int strip_size, ADIOI_PVFS2_fs *pvfs2_fs, open_status *o_status) { int ret; PVFS_sysresp_lookup resp_lookup; PVFS_sysresp_getparent resp_getparent; PVFS_sysresp_create resp_create; PVFS_sys_attr attribs; PVFS_sys_dist* dist; ADIOI_PVFS2_makeattribs(&attribs); if (nr_datafiles > 0 ) { attribs.dfile_count = nr_datafiles; attribs.mask |= PVFS_ATTR_SYS_DFILE_COUNT; } dist = NULL; memset(&resp_lookup, 0, sizeof(resp_lookup)); memset(&resp_getparent, 0, sizeof(resp_getparent)); memset(&resp_create, 0, sizeof(resp_create)); ret = PVFS_sys_lookup(fs_id, pvfs_name, &(pvfs2_fs->credentials), &resp_lookup, PVFS2_LOOKUP_LINK_FOLLOW); if ( (ret < 0) ) { /* XXX: check what the error was */ if (access_mode & ADIO_CREATE) { ret = PVFS_sys_getparent(fs_id, pvfs_name, &(pvfs2_fs->credentials), &resp_getparent); if (ret < 0) { FPRINTF(stderr, "pvfs_sys_getparent returns with %d\n", ret); o_status->error = ret; return; } /* Set the distribution strip size if specified */ if (0 < strip_size) { /* Note that the distribution is hardcoded here */ dist = PVFS_sys_dist_lookup("simple_stripe"); ret = PVFS_sys_dist_setparam(dist, "strip_size", &strip_size); if (ret < 0) { FPRINTF(stderr, "pvfs_sys_dist_setparam returns with %d\n", ret); o_status->error = ret; } } /* Perform file creation */ ret = PVFS_sys_create(resp_getparent.basename, resp_getparent.parent_ref, attribs, &(pvfs2_fs->credentials), dist, &resp_create); if (ret < 0) { /* XXX: should only do this for EEXISTS */ ret = PVFS_sys_lookup(fs_id, pvfs_name, &(pvfs2_fs->credentials), &resp_lookup, PVFS2_LOOKUP_LINK_FOLLOW); if ( ret < 0 ) { o_status->error = ret; return; } o_status->error = ret; o_status->object_ref = resp_lookup.ref; return; } o_status->object_ref = resp_create.ref; } else { FPRINTF(stderr, "cannot create file without MPI_MODE_CREATE\n"); o_status->error = ret; return; } } else if (access_mode & ADIO_EXCL) { /* lookup should not succeed if opened with EXCL */ o_status->error = -1; /* XXX: what should it be? */ return; } else { o_status->object_ref = resp_lookup.ref; } o_status->error = ret; return; }