Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
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;

}