Beispiel #1
0
static int
_posix_xattr_get_set_from_backend (posix_xattr_filler_t *filler, char *key)
{
        ssize_t  xattr_size = -1;
        int      ret        = 0;
        char    *value      = NULL;

        xattr_size = sys_lgetxattr (filler->real_path, key, NULL, 0);

        if (xattr_size > 0) {
                value = GF_CALLOC (1, xattr_size + 1,
                                   gf_posix_mt_char);
                if (!value)
                        goto out;

                xattr_size = sys_lgetxattr (filler->real_path, key, value,
                                            xattr_size);
                if (xattr_size <= 0) {
                        gf_log (filler->this->name, GF_LOG_WARNING,
                                "getxattr failed. path: %s, key: %s",
                                filler->real_path, key);
                        GF_FREE (value);
                        goto out;
                }
Beispiel #2
0
/*
 * Function: sys_get_easize
 *
 * Purpose: get size of a native EA
 *
 * Arguments:
 *
 *    vol          (r) current volume
 *    rbuf         (w) DSI reply buffer
 *    rbuflen      (rw) current length of data in reply buffer
 *    uname        (r) filename
 *    oflag        (r) link and create flag
 *    attruname    (r) name of attribute
 *
 * Returns: AFP code: AFP_OK on success or appropiate AFP error code
 *
 * Effects:
 *
 * Copies EA size into rbuf in network order. Increments *rbuflen +4.
 */
int sys_get_easize(VFS_FUNC_ARGS_EA_GETSIZE)
{
    ssize_t   ret;
    uint32_t  attrsize;

    LOG(log_debug7, logtype_afpd, "sys_getextattr_size(%s): attribute: \"%s\"", uname, attruname);

    if ((oflag & O_NOFOLLOW) ) {
        ret = sys_lgetxattr(uname, attruname, rbuf +4, 0);
    }
    else {
        ret = sys_getxattr(uname, attruname,  rbuf +4, 0);
    }

    if (ret == -1) {
        memset(rbuf, 0, 4);
        *rbuflen += 4;
        switch(errno) {
        case OPEN_NOFOLLOW_ERRNO:
            /* its a symlink and client requested O_NOFOLLOW  */
            LOG(log_debug, logtype_afpd, "sys_getextattr_size(%s): symlink with kXAttrNoFollow", uname);
            return AFPERR_MISC;

        case ENOATTR:
        case ENOENT:
            return AFPERR_MISC;

        default:
            LOG(log_debug, logtype_afpd, "sys_getextattr_size: error: %s", strerror(errno));
            return AFPERR_MISC;
        }
    }

    if (ret > MAX_EA_SIZE)
        ret = MAX_EA_SIZE;

    /* Start building reply packet */
    LOG(log_debug7, logtype_afpd, "sys_getextattr_size(%s): attribute: \"%s\", size: %u", uname, attruname, ret);

    /* length of attribute data */
    attrsize = htonl((uint32_t)ret);
    memcpy(rbuf, &attrsize, 4);
    *rbuflen += 4;

    ret = AFP_OK;
    return ret;
}
Beispiel #3
0
/*
 * Function: sys_get_eacontent
 *
 * Purpose: copy native EA into rbuf
 *
 * Arguments:
 *
 *    vol          (r) current volume
 *    rbuf         (w) DSI reply buffer
 *    rbuflen      (rw) current length of data in reply buffer
 *    uname        (r) filename
 *    oflag        (r) link and create flag
 *    attruname    (r) name of attribute
 *    maxreply     (r) maximum EA size as of current specs/real-life
 *
 * Returns: AFP code: AFP_OK on success or appropiate AFP error code
 *
 * Effects:
 *
 * Copies EA into rbuf. Increments *rbuflen accordingly.
 */
int sys_get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT)
{
    ssize_t   ret;
    uint32_t  attrsize;

    /* Start building reply packet */

    maxreply -= MAX_REPLY_EXTRA_BYTES;

    if (maxreply > MAX_EA_SIZE)
        maxreply = MAX_EA_SIZE;

    LOG(log_debug7, logtype_afpd, "sys_getextattr_content(%s): attribute: \"%s\", size: %u", uname, attruname, maxreply);

    if ((oflag & O_NOFOLLOW) ) {
        ret = sys_lgetxattr(uname, attruname, rbuf +4, maxreply);
    }
    else {
        ret = sys_getxattr(uname, attruname,  rbuf +4, maxreply);
    }

    if (ret == -1) {
        memset(rbuf, 0, 4);
        *rbuflen += 4;
        switch(errno) {
        case OPEN_NOFOLLOW_ERRNO:
            /* its a symlink and client requested O_NOFOLLOW  */
            LOG(log_debug, logtype_afpd, "sys_getextattr_content(%s): symlink with kXAttrNoFollow", uname);
            return AFPERR_MISC;

        case ENOATTR:
            return AFPERR_MISC;

        default:
            LOG(log_debug, logtype_afpd, "sys_getextattr_content(%s): error: %s", attruname, strerror(errno));
            return AFPERR_MISC;
        }
    }

    /* remember where we must store length of attribute data in rbuf */
    *rbuflen += 4 +ret;

    attrsize = htonl((uint32_t)ret);
    memcpy(rbuf, &attrsize, 4);

    return AFP_OK;
}
Beispiel #4
0
static char *
parse_and_validate_args (int argc, char *argv[])
{
        char        *basedir = NULL;
        struct stat  d = {0, };
        int          ret = -1;
#ifndef __FreeBSD__
        unsigned char volume_id[16];
#endif /* __FreeBSD__ */
        char        *slv_mnt = NULL;

        if (argc != 4) {
                err ("Usage: %s <DIR> <SLAVE-VOL-MOUNT> <CRAWL-THREAD-COUNT>\n",
                      argv[0]);
                return NULL;
        }

        basedir = argv[1];
        ret = sys_lstat (basedir, &d);
        if (ret) {
                err ("%s: %s\n", basedir, strerror (errno));
                return NULL;
        }

#ifndef __FreeBSD__
        ret = sys_lgetxattr (basedir, "trusted.glusterfs.volume-id",
                             volume_id, 16);
        if (ret != 16) {
                err ("%s:Not a valid brick path.\n", basedir);
                return NULL;
        }
#endif /* __FreeBSD__ */

        slv_mnt = argv[2];
        ret = sys_lstat (slv_mnt, &d);
        if (ret) {
                err ("%s: %s\n", slv_mnt, strerror (errno));
                return NULL;
        }
        slavemnt = argv[2];

        workers = atoi(argv[3]);
        if (workers <= 0)
                workers = DEFAULT_WORKERS;

        return basedir;
}
Beispiel #5
0
static int stat_xattr(const char *fname, STRUCT_STAT *fst)
{
	int mode, rdev_major, rdev_minor, uid, gid, len;
	char buf[256];

	if (am_root >= 0 || IS_DEVICE(fst->st_mode) || IS_SPECIAL(fst->st_mode))
		return -1;

	len = sys_lgetxattr(fname, XSTAT_ATTR, buf, sizeof buf - 1);
	if (len >= (int)sizeof buf) {
		len = -1;
		errno = ERANGE;
	}
	if (len < 0) {
		if (errno == ENOTSUP || errno == ENOATTR)
			return -1;
		if (errno == EPERM && S_ISLNK(fst->st_mode)) {
			fst->st_uid = 0;
			fst->st_gid = 0;
			return 0;
		}
		fprintf(stderr, "failed to read xattr %s for %s: %s\n",
			XSTAT_ATTR, fname, strerror(errno));
		return -1;
	}
	buf[len] = '\0';

	if (sscanf(buf, "%o %d,%d %d:%d",
		   &mode, &rdev_major, &rdev_minor, &uid, &gid) != 5) {
		fprintf(stderr, "Corrupt %s xattr attached to %s: \"%s\"\n",
			XSTAT_ATTR, fname, buf);
		exit(1);
	}

#if _S_IFLNK != 0120000
	if ((mode & (_S_IFMT)) == 0120000)
		mode = (mode & ~(_S_IFMT)) | _S_IFLNK;
#endif
	fst->st_mode = mode;

	fst->st_rdev = MAKEDEV(rdev_major, rdev_minor);
	fst->st_uid = uid;
	fst->st_gid = gid;

	return 0;
}
Beispiel #6
0
/*
 * Function: sys_get_easize
 *
 * Purpose: get size of a native EA
 *
 * Arguments:
 *
 *    vol          (r) current volume
 *    rbuf         (w) DSI reply buffer
 *    rbuflen      (rw) current length of data in reply buffer
 *    uname        (r) filename
 *    oflag        (r) link and create flag
 *    attruname    (r) name of attribute
 *
 * Returns: AFP code: AFP_OK on success or appropiate AFP error code
 *
 * Effects:
 *
 * Copies EA size into rbuf in network order. Increments *rbuflen +4.
 */
int sys_get_easize(VFS_FUNC_ARGS_EA_GETSIZE)
{
    ssize_t   ret;
    uint32_t  attrsize;

    LOG(log_debug7, logtype_afpd, "sys_getextattr_size(%s): attribute: \"%s\"", uname, attruname);

    /* PBaranski fix */
    if (fd != -1) {
	LOG(log_debug, logtype_afpd, "sys_get_easize(%s): file is already opened", uname);
	ret = sys_fgetxattr(fd, attruname, rbuf +4, 0);
    } else {
	if ((oflag & O_NOFOLLOW) ) {
    	    ret = sys_lgetxattr(uname, attruname, rbuf +4, 0);
	}
	else {
    	    ret = sys_getxattr(uname, attruname,  rbuf +4, 0);
	}
    }
    /* PBaranski fix */

    
    if (ret == -1) {
        memset(rbuf, 0, 4);
        *rbuflen += 4;
        switch(errno) {
        case OPEN_NOFOLLOW_ERRNO:
            /* its a symlink and client requested O_NOFOLLOW  */
            LOG(log_debug, logtype_afpd, "sys_getextattr_size(%s): symlink with kXAttrNoFollow", uname);
            return AFPERR_MISC;

        case ENOATTR:
        case ENOENT:
            if (vol->v_obj->afp_version >= 34)
                return AFPERR_NOITEM;
            return AFPERR_MISC;

        default:
            LOG(log_debug, logtype_afpd, "sys_getextattr_size: error: %s", strerror(errno));
            return AFPERR_MISC;
        }
    }

    if (ret > MAX_EA_SIZE) 
      ret = MAX_EA_SIZE;

    if (vol->v_flags & AFPVOL_EA_SAMBA) {
        /* What can we do about xattrs that are 1 byte large? */
        if (ret < 2) {
            memset(rbuf, 0, 4);
            *rbuflen += 4;

            if (vol->v_obj->afp_version >= 34) {
                return AFPERR_NOITEM;
            }
            return AFPERR_MISC;
        }
        ret--;
    }

    /* Start building reply packet */
    LOG(log_debug7, logtype_afpd, "sys_getextattr_size(%s): attribute: \"%s\", size: %u", uname, attruname, ret);

    /* length of attribute data */
    attrsize = htonl((uint32_t)ret);
    memcpy(rbuf, &attrsize, 4);
    *rbuflen += 4;

    ret = AFP_OK;
    return ret;
}
Beispiel #7
0
/*
 * Function: sys_get_eacontent
 *
 * Purpose: copy native EA into rbuf
 *
 * Arguments:
 *
 *    vol          (r) current volume
 *    rbuf         (w) DSI reply buffer
 *    rbuflen      (rw) current length of data in reply buffer
 *    uname        (r) filename
 *    oflag        (r) link and create flag
 *    attruname    (r) name of attribute
 *    maxreply     (r) maximum EA size as of current specs/real-life
 *    fd           (r) file descriptor
 * Returns: AFP code: AFP_OK on success or appropiate AFP error code
 *
 * Effects:
 *
 * Copies EA into rbuf. Increments *rbuflen accordingly.
 */
int sys_get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT)
{
    ssize_t   ret;
    uint32_t  attrsize;

    /* Start building reply packet */

    maxreply -= MAX_REPLY_EXTRA_BYTES;

    if (maxreply > MAX_EA_SIZE)
        maxreply = MAX_EA_SIZE;

    LOG(log_debug7, logtype_afpd, "sys_getextattr_content(%s): attribute: \"%s\", size: %u", uname, attruname, maxreply);
    if (vol->v_flags & AFPVOL_EA_SAMBA) {
        maxreply++;
    }

    /* PBaranski fix */
    if (fd != -1) {
	LOG(log_debug, logtype_afpd, "sys_get_eacontent(%s): file is already opened", uname);
	ret = sys_fgetxattr(fd, attruname, rbuf +4, maxreply);
    } else {
	if ((oflag & O_NOFOLLOW) ) {
    	    ret = sys_lgetxattr(uname, attruname, rbuf +4, maxreply);
	}
	else {
    	    ret = sys_getxattr(uname, attruname,  rbuf +4, maxreply);
	}
    }
    /* PBaranski fix */

    if (ret == -1) {
        memset(rbuf, 0, 4);
        *rbuflen += 4;
        switch(errno) {
        case OPEN_NOFOLLOW_ERRNO:
            /* its a symlink and client requested O_NOFOLLOW  */
            LOG(log_debug, logtype_afpd, "sys_getextattr_content(%s): symlink with kXAttrNoFollow", uname);
            return AFPERR_MISC;

        case ENOATTR:
            if (vol->v_obj->afp_version >= 34)
                return AFPERR_NOITEM;
            return AFPERR_MISC;

        default:
            LOG(log_debug, logtype_afpd, "sys_getextattr_content(%s): error: %s", attruname, strerror(errno));
            return AFPERR_MISC;
        }
    }

    if (vol->v_flags & AFPVOL_EA_SAMBA) {
        /* What can we do about xattrs that are 1 byte large? */
        if (ret < 2) {
            memset(rbuf, 0, 4);
            *rbuflen += 4;

            if (vol->v_obj->afp_version >= 34) {
                return AFPERR_NOITEM;
            }
            return AFPERR_MISC;
        }
        ret--;
    }

    /* remember where we must store length of attribute data in rbuf */
    *rbuflen += 4 +ret;

    attrsize = htonl((uint32_t)ret);
    memcpy(rbuf, &attrsize, 4);

    return AFP_OK;
}
Beispiel #8
0
ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
{
	return sys_lgetxattr(path, name, value, size);
}
Beispiel #9
0
int
main(int argc, char **argv)
{
    int ret = 0;
    struct stat st;
    char *dname = NULL;
    char *bname = NULL;
    ssize_t ret_size = 0;
    uuid_t pgfid_raw = {
        0,
    };
    char pgfid[36] = "";
    char xxh64[GF_XXH64_DIGEST_LENGTH * 2 + 1] = {
        0,
    };
    char pgfid_bname[1024] = {
        0,
    };
    char *key = NULL;
    char *val = NULL;
    size_t key_size = 0;
    size_t val_size = 0;
    const char *file_path = NULL;
    char *file_path1 = NULL;
    char *file_path2 = NULL;

    if (argc != 2) {
        fprintf(stderr, "Usage: setgfid2path <file-path>\n");
        return -1;
    }

    ret = sys_lstat(argv[1], &st);
    if (ret != 0) {
        fprintf(stderr, "Invalid File Path\n");
        return -1;
    }

    if (st.st_nlink >= MAX_GFID2PATH_LINK_SUP) {
        fprintf(stderr,
                "Number of Hardlink support exceeded. "
                "max=%d\n",
                MAX_GFID2PATH_LINK_SUP);
        return -1;
    }

    file_path = argv[1];
    file_path1 = strdup(file_path);
    file_path2 = strdup(file_path);

    dname = dirname(file_path1);
    bname = basename(file_path2);

    /* Get GFID of Parent directory */
    ret_size = sys_lgetxattr(dname, GFID_XATTR_KEY, pgfid_raw, GFID_SIZE);
    if (ret_size != GFID_SIZE) {
        fprintf(stderr, "Failed to get GFID of parent directory. dir=%s\n",
                dname);
        ret = -1;
        goto out;
    }

    /* Convert to UUID format */
    if (uuid_utoa_r(pgfid_raw, pgfid) == NULL) {
        fprintf(stderr,
                "Failed to format GFID of parent directory. "
                "dir=%s GFID=%s\n",
                dname, pgfid_raw);
        ret = -1;
        goto out;
    }

    /* Find xxhash for PGFID/BaseName */
    snprintf(pgfid_bname, sizeof(pgfid_bname), "%s/%s", pgfid, bname);
    gf_xxh64_wrapper((unsigned char *)pgfid_bname, strlen(pgfid_bname),
                     GF_XXHSUM64_DEFAULT_SEED, xxh64);

    key_size = SLEN(GFID2PATH_XATTR_KEY_PREFIX) + GF_XXH64_DIGEST_LENGTH * 2 +
               1;
    key = alloca(key_size);
    snprintf(key, key_size, GFID2PATH_XATTR_KEY_PREFIX "%s", xxh64);

    val_size = UUID_CANONICAL_FORM_LEN + NAME_MAX + 2;
    val = alloca(val_size);
    snprintf(val, val_size, "%s/%s", pgfid, bname);

    /* Set the Xattr, ignore if same key xattr already exists */
    ret = sys_lsetxattr(file_path, key, val, strlen(val), XATTR_CREATE);
    if (ret == -1) {
        if (errno == EEXIST) {
            printf("Xattr already exists, ignoring..\n");
            ret = 0;
            goto out;
        }

        fprintf(stderr, "Failed to set gfid2path xattr. errno=%d\n error=%s",
                errno, strerror(errno));
        ret = -1;
        goto out;
    }

    printf("Success. file=%s key=%s value=%s\n", file_path, key, val);

out:
    if (file_path1 != NULL)
        free(file_path1);

    if (file_path2 != NULL)
        free(file_path2);

    return ret;
}