ssize_t rep_flistxattr (int filedes, char *list, size_t size) { #if defined(HAVE_FLISTXATTR) #ifndef XATTR_ADDITIONAL_OPTIONS return flistxattr(filedes, list, size); #else /* So that we do not recursivly call this function */ #undef flistxattr int options = 0; return flistxattr(filedes, list, size, options); #endif #elif defined(HAVE_FLISTEA) return flistea(filedes, list, size); #elif defined(HAVE_EXTATTR_LIST_FD) extattr_arg arg; arg.filedes = filedes; return bsd_attr_list(2, arg, list, size); #elif defined(HAVE_ATTR_LISTF) return irix_attr_list(NULL, filedes, list, size, 0); #elif defined(HAVE_ATTROPEN) ssize_t ret = -1; int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0); if (attrdirfd >= 0) { ret = solaris_list_xattr(attrdirfd, list, size); close(attrdirfd); } return ret; #else errno = ENOSYS; return -1; #endif }
// list all keys, caller responsible for freeing void xattrkv_keys(int db, char ***keys, size_t *nkeys) { // flistxattr gives a buffer of null terminated strings // find out how much space to allocate size_t size = (size_t) flistxattr(db, NULL, 0, 0); char *buffer = malloc(size); flistxattr(db, buffer, size, 0); size_t keycount = 0; for (int i = 0; i < size; i++) { if (buffer[i] == '\0') { keycount++; } } *nkeys = keycount; *keys = malloc(sizeof(char*) * keycount); size_t index = 0; size_t bufpos = 0; // this is probably insane while (index != keycount) { *(*keys + index) = strdup(buffer+bufpos); bufpos = bufpos + strlen(*(*keys+index)) + 1; index = index + 1; } }
static INT64_T chirp_fs_local_flistxattr(int fd, char *list, size_t size) { #ifdef CCTOOLS_OPSYS_DARWIN return flistxattr(fd, list, size, 0); #else return flistxattr(fd, list, size); #endif }
static INT64_T chirp_fs_local_flistxattr(int fd, char *list, size_t size) { PREAMBLE("flistxattr(%d, %p, %zu)", fd, list, size); SETUP_FILE #ifdef CCTOOLS_OPSYS_DARWIN rc = flistxattr(lfd, list, size, 0); #else rc = flistxattr(lfd, list, size); #endif PROLOGUE }
ssize_t ceph_os_flistxattr(int fd, char *list, size_t size) { ssize_t error = -1; #if defined(__FreeBSD__) /* * XXX. The format of the list FreeBSD returns differs * from the Linux ones. We have to perform the conversion. :-( */ char *newlist, *p, *p1; if (size != 0) { newlist = malloc(size); if (newlist != NULL) { error = extattr_list_fd(fd, EXTATTR_NAMESPACE_USER, newlist, size); if (error > 0) { p = newlist; p1 = list; while ((p - newlist) < error) { uint8_t len = *(uint8_t *)p; p++; if ((p + len - newlist) > error) break; if (len > 0) { bcopy(p, p1, len); p += len; p1 += len; *p1++ = '\0'; } } error = p1 - list; } free(newlist); } } else { error = extattr_list_fd(fd, EXTATTR_NAMESPACE_USER, list, size); } #elif defined(__linux__) //提取文件的所有属性列表 error = flistxattr(fd, list, size); #elif defined(__APPLE__) error = flistxattr(fd, list, size, 0); #endif return (error); }
ssize_t mdir_list_xattr(mdir_t *mdir, char *list, size_t size) { ssize_t status; status = flistxattr(mdir->fdp, list, size); return status; }
ssize_t mslnk_list_xattr(mslnk_t *mslnk, char *list, size_t size) { ssize_t status; status = flistxattr(mslnk->fdattrs, list, size); return status; }
static int check_suitable_buf(const int file, long size) { int n; char buf[size]; n = flistxattr(file, buf, sizeof(buf)); return n != -1; }
static ssize_t xattr_flistxattr(int fd, char *namebuf, size_t size, int options) { if (!(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { return -1; } if (options & XATTR_XATTR_NOFOLLOW) { return -1; } else { return flistxattr(fd, namebuf, size); } }
ssize_t sys_flistxattr (int filedes, char *list, size_t size) { #if defined(HAVE_FLISTXATTR) return flistxattr(filedes, list, size); #elif defined(HAVE_ATTR_LISTF) return irix_attr_list(NULL, filedes, list, size, 0); #else errno = ENOSYS; return -1; #endif }
JNIEXPORT jint JNICALL Java_sun_nio_fs_LinuxNativeDispatcher_flistxattr(JNIEnv* env, jclass clazz, jint fd, jlong listAddress, jint size) { size_t res = -1; char* list = jlong_to_ptr(listAddress); res = flistxattr (fd, list, (size_t)size); if (res == (size_t)-1) throwUnixException(env, errno); return (jint)res; }
static void verify_flistxattr(unsigned int n) { TEST(flistxattr(fd[n], NULL, 0)); if (TEST_RETURN == -1) { tst_res(TFAIL | TTERRNO, "flistxattr() failed"); return; } if (check_suitable_buf(fd[n], TEST_RETURN)) tst_res(TPASS, "flistxattr() succeed with suitable buffer"); else tst_res(TFAIL, "flistxattr() failed with small buffer"); }
int verify_orig_file_xattr(enum FILE_TYPE ft, char *filename, unsigned long list_size) { unsigned long j; int ret = 0, fd; /*List all EA names if xattr_nums *(xattr_name_sz+1) less than 65536*/ fd = open64(filename, open_ro_flags); for (j = 0; j < xattr_nums; j++) memset(xattr_name_list_get[j], 0, xattr_name_sz + 1); switch (ft) { case NORMAL: ret = flistxattr(fd, (void *)list, list_size); break; case SYMLINK: ret = llistxattr(filename, (void *)list, list_size); break; case DIRECTORY: ret = listxattr(filename, (void *)list, list_size); break; default: break; } list_parser(list); for (j = 0; j < xattr_nums; j++) { if (!is_namelist_member(xattr_nums, xattr_name_list_get[j], xattr_name_list_set)) { fprintf(stderr, "Xattr list name(%s) " "did not match the orginal one\n", xattr_name_list_get[j]); ret = -1; return ret; } } close(fd); return 0; }
static void verify_flistxattr(unsigned int n) { struct test_case *t = tc + n; char buf[t->size]; TEST(flistxattr(*t->fd, buf, t->size)); if (TEST_RETURN != -1) { tst_res(TFAIL, "flistxattr() succeeded unexpectedly (returned %ld)", TEST_RETURN); return; } if (t->exp_err != TEST_ERRNO) { tst_res(TFAIL | TTERRNO, "flistxattr() failed " "unexpectedlly, expected %s", tst_strerrno(t->exp_err)); } else { tst_res(TPASS | TTERRNO, "flistxattr() failed as expected"); } }
/** * return index if found, * negative value on error. */ static int xattr_name_to_id(int fd, const char *name) { unsigned int i; char names[MAXPATHLEN], *ptr; ssize_t namesize; /* get xattrs */ namesize = flistxattr(fd, names, sizeof(names)); if (namesize < 0) return -ERR_FSAL_NOENT; if (!strncmp(name, "system.posix_acl_access", MAXNAMLEN)) return XATTR_SYSTEM; for (ptr = names, i = 0; ptr < names + namesize; i++, ptr += strlen(ptr) + 1) { if (!strcmp(name, ptr)) return i + XATTR_COUNT; } return -ERR_FSAL_NOENT; }
static int xattr_id_to_name(int fd, unsigned int xattr_id, char *name) { unsigned int index; unsigned int curr_idx; char names[MAXPATHLEN], *ptr; ssize_t namesize; size_t len = 0; if (xattr_id < XATTR_COUNT) return ERR_FSAL_INVAL; index = xattr_id - XATTR_COUNT; /* get xattrs */ namesize = flistxattr(fd, names, sizeof(names)); if (namesize < 0) return ERR_FSAL_NOENT; errno = 0; if (xattr_id == XATTR_SYSTEM) { strcpy(name, "system.posix_acl_access"); return ERR_FSAL_NO_ERROR; } for (ptr = names, curr_idx = 0; ptr < names + namesize; curr_idx++, ptr += len + 1) { len = strlen(ptr); if (curr_idx == index) { strcpy(name, ptr); return ERR_FSAL_NO_ERROR; } } return ERR_FSAL_NOENT; }
static int setup_xattrs(struct archive_read_disk *a, struct archive_entry *entry, int *fd) { char *list, *p; const char *path; ssize_t list_size; path = archive_entry_sourcepath(entry); if (path == NULL) path = archive_entry_pathname(entry); if (*fd < 0 && a->tree != NULL) { if (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK) *fd = a->open_on_current_dir(a->tree, path, O_RDONLY | O_NONBLOCK); if (*fd < 0) { if (a->tree_enter_working_dir(a->tree) != 0) { archive_set_error(&a->archive, errno, "Couldn't access %s", path); return (ARCHIVE_FAILED); } } } #if HAVE_FLISTXATTR if (*fd >= 0) list_size = flistxattr(*fd, NULL, 0); else if (!a->follow_symlinks) list_size = llistxattr(path, NULL, 0); else list_size = listxattr(path, NULL, 0); #elif HAVE_FLISTEA if (*fd >= 0) list_size = flistea(*fd, NULL, 0); else if (!a->follow_symlinks) list_size = llistea(path, NULL, 0); else list_size = listea(path, NULL, 0); #endif if (list_size == -1) { if (errno == ENOTSUP || errno == ENOSYS) return (ARCHIVE_OK); archive_set_error(&a->archive, errno, "Couldn't list extended attributes"); return (ARCHIVE_WARN); } if (list_size == 0) return (ARCHIVE_OK); if ((list = malloc(list_size)) == NULL) { archive_set_error(&a->archive, errno, "Out of memory"); return (ARCHIVE_FATAL); } #if HAVE_FLISTXATTR if (*fd >= 0) list_size = flistxattr(*fd, list, list_size); else if (!a->follow_symlinks) list_size = llistxattr(path, list, list_size); else list_size = listxattr(path, list, list_size); #elif HAVE_FLISTEA if (*fd >= 0) list_size = flistea(*fd, list, list_size); else if (!a->follow_symlinks) list_size = llistea(path, list, list_size); else list_size = listea(path, list, list_size); #endif if (list_size == -1) { archive_set_error(&a->archive, errno, "Couldn't retrieve extended attributes"); free(list); return (ARCHIVE_WARN); } for (p = list; (p - list) < list_size; p += strlen(p) + 1) { if (strncmp(p, "system.", 7) == 0 || strncmp(p, "xfsroot.", 8) == 0) continue; setup_xattr(a, entry, p, *fd); } free(list); return (ARCHIVE_OK); }
int fd_based_fops_1 (char *filename) { int fd = 0; int ret = -1; struct stat stbuf = {0,}; char wstr[50] = {0,}; char rstr[50] = {0,}; fd = open (filename, O_RDWR|O_CREAT); if (fd < 0) { fd = 0; fprintf (stderr, "open failed : %s\n", strerror (errno)); goto out; } ret = unlink (filename); if (ret < 0) { fprintf (stderr, "unlink failed : %s\n", strerror (errno)); goto out; } strcpy (wstr, "This is my string\n"); ret = write (fd, wstr, strlen(wstr)); if (ret <= 0) { ret = -1; fprintf (stderr, "write failed: %s\n", strerror (errno)); goto out; } ret = lseek (fd, 0, SEEK_SET); if (ret < 0) { fprintf (stderr, "lseek failed: %s\n", strerror (errno)); goto out; } ret = read (fd, rstr, strlen(wstr)); if (ret <= 0) { ret = -1; fprintf (stderr, "read failed: %s\n", strerror (errno)); goto out; } ret = memcmp (rstr, wstr, strlen (wstr)); if (ret != 0) { ret = -1; fprintf (stderr, "read returning junk\n"); goto out; } ret = ftruncate (fd, 0); if (ret < 0) { fprintf (stderr, "ftruncate failed : %s\n", strerror (errno)); goto out; } ret = fstat (fd, &stbuf); if (ret < 0) { fprintf (stderr, "fstat failed : %s\n", strerror (errno)); goto out; } ret = fchmod (fd, 0640); if (ret < 0) { fprintf (stderr, "fchmod failed : %s\n", strerror (errno)); goto out; } ret = fchown (fd, 10001, 10001); if (ret < 0) { fprintf (stderr, "fchown failed : %s\n", strerror (errno)); goto out; } ret = fsync (fd); if (ret < 0) { fprintf (stderr, "fsync failed : %s\n", strerror (errno)); goto out; } ret = fsetxattr (fd, "trusted.xattr-test", "working", 8, 0); if (ret < 0) { fprintf (stderr, "fsetxattr failed : %s\n", strerror (errno)); goto out; } ret = fdatasync (fd); if (ret < 0) { fprintf (stderr, "fdatasync failed : %s\n", strerror (errno)); goto out; } ret = flistxattr (fd, NULL, 0); if (ret <= 0) { ret = -1; fprintf (stderr, "flistxattr failed : %s\n", strerror (errno)); goto out; } ret = fgetxattr (fd, "trusted.xattr-test", NULL, 0); if (ret <= 0) { ret = -1; fprintf (stderr, "fgetxattr failed : %s\n", strerror (errno)); goto out; } ret = fremovexattr (fd, "trusted.xattr-test"); if (ret < 0) { fprintf (stderr, "fremovexattr failed : %s\n", strerror (errno)); goto out; } ret = 0; out: if (fd) close (fd); return ret; }
XAErrorCode XAFileLoadAttributes(XAFileRef fileRef) { XAErrorCode eCode = XAErrorImmaterial; CFIndex bSize = CFStringGetLength(fileRef->path) + 0x01; char *buffer = calloc(bSize, sizeof(*buffer)); if(CFStringGetCString(fileRef->path, buffer, bSize, kCFStringEncodingUTF8)) { int fd = open(buffer, O_RDONLY, 0x00); if(fd > 0x00) { char *keys = 0x00; size_t size = 0x00; int options = 0x00; CFArrayRemoveAllValues(fileRef->attributes); size = flistxattr(fd, keys, size, options); if(size > 0x00) { CFAllocatorRef allocator = CFGetAllocator(fileRef); char *key = 0x00; keys = calloc(size, sizeof(*keys)); size = flistxattr(fd, keys, size, options); eCode = XAErrorNone; for(key = keys; key < keys + size; key += 0x01 + strlen(key)) { XAAttributeRef attributeRef = 0x00; attributeRef = XAAttributeCreate(allocator); if(XAAttributeLoadFileDescriptor(attributeRef, fd, key)) { CFArrayAppendValue(fileRef->attributes, attributeRef); CFRelease(attributeRef); }else { CFRelease(attributeRef); eCode = XAErrorImmaterial; break; } } }else { eCode = XAErrorImmaterial; //fprintf(stderr, "listxattr error: %s\n", strerr(errno)); } close(fd); } } fileRef->edited = 0x00; free(buffer); return(eCode); }
fsal_status_t vfs_list_ext_attrs(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx, unsigned int argcookie, fsal_xattrent_t *xattrs_tab, unsigned int xattrs_tabsize, unsigned int *p_nb_returned, int *end_of_list) { unsigned int index; unsigned int out_index; unsigned int cookie = argcookie; struct vfs_fsal_obj_handle *obj_handle = NULL; int fd = -1; fsal_errors_t fe; char names[MAXPATHLEN], *ptr; ssize_t namesize; int xattr_idx; obj_handle = container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle); /* Deal with special cookie */ if (cookie == XATTR_RW_COOKIE) cookie = XATTR_COUNT; for (index = cookie, out_index = 0; index < XATTR_COUNT && out_index < xattrs_tabsize; index++) { if (do_match_type (xattr_list[index].flags, obj_hdl->attributes.type)) { /* fills an xattr entry */ xattrs_tab[out_index].xattr_id = index; strncpy(xattr_list[index].xattr_name, xattrs_tab[out_index].xattr_name, MAXNAMLEN); xattrs_tab[out_index].xattr_cookie = index + 1; /* set asked attributes (all supported) */ xattrs_tab[out_index].attributes.mask = obj_hdl->attributes.mask; if (file_attributes_to_xattr_attrs (&obj_hdl->attributes, &xattrs_tab[out_index].attributes, index)) { /* set error flag */ xattrs_tab[out_index].attributes.mask = ATTR_RDATTR_ERR; } /* next output slot */ out_index++; } } /* save a call if output array is full */ if (out_index == xattrs_tabsize) { *end_of_list = FALSE; *p_nb_returned = out_index; return fsalstat(ERR_FSAL_NO_ERROR, 0); } /* get the path of the file in Lustre */ fd = (obj_hdl->type == DIRECTORY) ? vfs_fsal_open(obj_handle, O_DIRECTORY, &fe) : vfs_fsal_open(obj_handle, O_RDWR, &fe); if (fd < 0) return fsalstat(fe, -fd); /* get xattrs */ namesize = flistxattr(fd, names, sizeof(names)); if (namesize >= 0) { size_t len = 0; errno = 0; for (ptr = names, xattr_idx = 0; (ptr < names + namesize) && (out_index < xattrs_tabsize); xattr_idx++, ptr += len + 1) { len = strlen(ptr); index = XATTR_COUNT + xattr_idx; /* skip if index is before cookie */ if (index < cookie) continue; /* fills an xattr entry */ xattrs_tab[out_index].xattr_id = index; strncpy(xattrs_tab[out_index].xattr_name, ptr, len + 1); xattrs_tab[out_index].xattr_cookie = index + 1; /* set asked attributes (all supported) */ xattrs_tab[out_index].attributes.mask = obj_hdl->attributes.mask; if (file_attributes_to_xattr_attrs (&obj_hdl->attributes, &xattrs_tab[out_index].attributes, index)) { /* set error flag */ xattrs_tab[out_index].attributes.mask = ATTR_RDATTR_ERR; } /* next output slot */ out_index++; } /* all xattrs are in the output array */ if (ptr >= names + namesize) *end_of_list = TRUE; else *end_of_list = FALSE; } else /* no xattrs */ *end_of_list = TRUE; *p_nb_returned = out_index; close(fd); return fsalstat(ERR_FSAL_NO_ERROR, 0); }
/* get all xattrs from file given by FILE_NAME or FD (when non-zero). This includes all the user.*, security.*, system.*, etc. available domains */ void xattrs_xattrs_get (int parentfd, char const *file_name, struct tar_stat_info *st, int fd) { if (xattrs_option > 0) { #ifndef HAVE_XATTRS static int done = 0; if (!done) WARN ((0, 0, _("XATTR support is not available"))); done = 1; #else static size_t xsz = 1024; static char *xatrs = NULL; ssize_t xret = -1; if (!xatrs) xatrs = x2nrealloc (xatrs, &xsz, 1); while (((fd == 0) ? ((xret = llistxattrat (parentfd, file_name, xatrs, xsz)) == -1) : ((xret = flistxattr (fd, xatrs, xsz)) == -1)) && (errno == ERANGE)) { xatrs = x2nrealloc (xatrs, &xsz, 1); } if (xret == -1) call_arg_warn ((fd == 0) ? "llistxattrat" : "flistxattr", file_name); else { const char *attr = xatrs; static size_t asz = 1024; static char *val = NULL; if (!val) val = x2nrealloc (val, &asz, 1); while (xret > 0) { size_t len = strlen (attr); ssize_t aret = 0; /* Archive all xattrs during creation, decide at extraction time * which ones are of interest/use for the target filesystem. */ while (((fd == 0) ? ((aret = lgetxattrat (parentfd, file_name, attr, val, asz)) == -1) : ((aret = fgetxattr (fd, attr, val, asz)) == -1)) && (errno == ERANGE)) { val = x2nrealloc (val, &asz, 1); } if (aret != -1) xheader_xattr_add (st, attr, val, aret); else if (errno != ENOATTR) call_arg_warn ((fd == 0) ? "lgetxattrat" : "fgetxattr", file_name); attr += len + 1; xret -= len + 1; } } #endif } }
static int setup_xattrs(struct archive_read_disk *a, struct archive_entry *entry, int *fd) { char *list, *p; const char *path; ssize_t list_size; path = NULL; if (*fd < 0) { path = archive_read_disk_entry_setup_path(a, entry, fd); if (path == NULL) return (ARCHIVE_WARN); } if (*fd >= 0) { #if ARCHIVE_XATTR_LINUX list_size = flistxattr(*fd, NULL, 0); #elif ARCHIVE_XATTR_DARWIN list_size = flistxattr(*fd, NULL, 0, 0); #elif ARCHIVE_XATTR_AIX list_size = flistea(*fd, NULL, 0); #endif } else if (!a->follow_symlinks) { #if ARCHIVE_XATTR_LINUX list_size = llistxattr(path, NULL, 0); #elif ARCHIVE_XATTR_DARWIN list_size = listxattr(path, NULL, 0, XATTR_NOFOLLOW); #elif ARCHIVE_XATTR_AIX list_size = llistea(path, NULL, 0); #endif } else { #if ARCHIVE_XATTR_LINUX list_size = listxattr(path, NULL, 0); #elif ARCHIVE_XATTR_DARWIN list_size = listxattr(path, NULL, 0, 0); #elif ARCHIVE_XATTR_AIX list_size = listea(path, NULL, 0); #endif } if (list_size == -1) { if (errno == ENOTSUP || errno == ENOSYS) return (ARCHIVE_OK); archive_set_error(&a->archive, errno, "Couldn't list extended attributes"); return (ARCHIVE_WARN); } if (list_size == 0) return (ARCHIVE_OK); if ((list = malloc(list_size)) == NULL) { archive_set_error(&a->archive, errno, "Out of memory"); return (ARCHIVE_FATAL); } if (*fd >= 0) { #if ARCHIVE_XATTR_LINUX list_size = flistxattr(*fd, list, list_size); #elif ARCHIVE_XATTR_DARWIN list_size = flistxattr(*fd, list, list_size, 0); #elif ARCHIVE_XATTR_AIX list_size = flistea(*fd, list, list_size); #endif } else if (!a->follow_symlinks) { #if ARCHIVE_XATTR_LINUX list_size = llistxattr(path, list, list_size); #elif ARCHIVE_XATTR_DARWIN list_size = listxattr(path, list, list_size, XATTR_NOFOLLOW); #elif ARCHIVE_XATTR_AIX list_size = llistea(path, list, list_size); #endif } else { #if ARCHIVE_XATTR_LINUX list_size = listxattr(path, list, list_size); #elif ARCHIVE_XATTR_DARWIN list_size = listxattr(path, list, list_size, 0); #elif ARCHIVE_XATTR_AIX list_size = listea(path, list, list_size); #endif } if (list_size == -1) { archive_set_error(&a->archive, errno, "Couldn't retrieve extended attributes"); free(list); return (ARCHIVE_WARN); } for (p = list; (p - list) < list_size; p += strlen(p) + 1) { #if ARCHIVE_XATTR_LINUX /* Linux: skip POSIX.1e ACL extended attributes */ if (strncmp(p, "system.", 7) == 0 && (strcmp(p + 7, "posix_acl_access") == 0 || strcmp(p + 7, "posix_acl_default") == 0)) continue; if (strncmp(p, "trusted.SGI_", 12) == 0 && (strcmp(p + 12, "ACL_DEFAULT") == 0 || strcmp(p + 12, "ACL_FILE") == 0)) continue; /* Linux: xfsroot namespace is obsolete and unsupported */ if (strncmp(p, "xfsroot.", 8) == 0) continue; #endif setup_xattr(a, entry, p, *fd, path); } free(list); return (ARCHIVE_OK); }
/* Copy extended attributes from src_path to dst_path. If the file has an extended Access ACL (system.posix_acl_access) and that is copied successfully, the file mode permission bits are copied as a side effect. This may not always the case, so the file mode and/or ownership must be copied separately. */ int attr_copy_fd(const char *src_path, int src_fd, const char *dst_path, int dst_fd, int (*check) (const char *, struct error_context *), struct error_context *ctx) { #if defined(HAVE_FLISTXATTR) && defined(HAVE_FGETXATTR) && \ defined(HAVE_FSETXATTR) int ret = 0; ssize_t size; char *names = NULL, *end_names, *name, *value = NULL; unsigned int setxattr_ENOTSUP = 0; /* ignore acls by default */ if (check == NULL) check = attr_copy_check_permissions; size = flistxattr (src_fd, NULL, 0); if (size < 0) { if (errno != ENOSYS && errno != ENOTSUP) { const char *qpath = quote (ctx, src_path); error (ctx, _("listing attributes of %s"), qpath); quote_free (ctx, qpath); ret = -1; } goto getout; } names = (char *) my_alloc (size+1); if (names == NULL) { error (ctx, ""); ret = -1; goto getout; } size = flistxattr (src_fd, names, size); if (size < 0) { const char *qpath = quote (ctx, src_path); error (ctx, _("listing attributes of %s"), qpath); quote_free (ctx, qpath); ret = -1; goto getout; } else { names[size] = '\0'; end_names = names + size; } for (name = names; name != end_names; name = strchr(name, '\0') + 1) { void *old_value; /* check if this attribute shall be preserved */ if (!*name || !check(name, ctx)) continue; size = fgetxattr (src_fd, name, NULL, 0); if (size < 0) { const char *qpath = quote (ctx, src_path); const char *qname = quote (ctx, name); error (ctx, _("getting attribute %s of %s"), qpath, qname); quote_free (ctx, qname); quote_free (ctx, qpath); ret = -1; continue; } value = (char *) realloc (old_value = value, size); if (size != 0 && value == NULL) { free(old_value); error (ctx, ""); ret = -1; } size = fgetxattr (src_fd, name, value, size); if (size < 0) { const char *qpath = quote (ctx, src_path); const char *qname = quote (ctx, name); error (ctx, _("getting attribute %s of %s"), qname, qpath); quote_free (ctx, qname); quote_free (ctx, qpath); ret = -1; continue; } if (fsetxattr (dst_fd, name, value, size, 0) != 0) { if (errno == ENOTSUP) setxattr_ENOTSUP++; else { const char *qpath = quote (ctx, dst_path); if (errno == ENOSYS) { error (ctx, _("setting attributes for " "%s"), qpath); ret = -1; break; /* no hope of getting any further */ } else { const char *qname = quote (ctx, name); error (ctx, _("setting attribute %s for %s"), qname, qpath); quote_free (ctx, qname); ret = -1; } quote_free (ctx, qpath); } } } if (setxattr_ENOTSUP) { const char *qpath = quote (ctx, dst_path); errno = ENOTSUP; error (ctx, _("setting attributes for %s"), qpath); ret = -1; quote_free (ctx, qpath); } getout: free (value); my_free (names); return ret; #else return 0; #endif }
/* * stress_xattr * stress the xattr operations */ int stress_xattr( uint64_t *const counter, const uint32_t instance, const uint64_t max_ops, const char *name) { pid_t pid = getpid(); int ret, fd, rc = EXIT_FAILURE; char filename[PATH_MAX]; ret = stress_temp_dir_mk(name, pid, instance); if (ret < 0) return exit_status(-ret); (void)stress_temp_filename(filename, sizeof(filename), name, pid, instance, mwc32()); (void)umask(0077); if ((fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) { rc = exit_status(errno); pr_fail_err(name, "open"); goto out; } (void)unlink(filename); do { int i, j; int ret; char attrname[32]; char value[32]; ssize_t sz; char *buffer; for (i = 0; i < 4096; i++) { snprintf(attrname, sizeof(attrname), "user.var_%d", i); snprintf(value, sizeof(value), "orig-value-%d", i); ret = fsetxattr(fd, attrname, value, strlen(value), XATTR_CREATE); if (ret < 0) { if (errno == ENOTSUP) { pr_inf(stderr, "%s stressor will be " "skipped, filesystem does not " "support xattr.\n", name); } if (errno == ENOSPC || errno == EDQUOT) break; pr_fail_err(name, "fsetxattr"); goto out_close; } } for (j = 0; j < i; j++) { snprintf(attrname, sizeof(attrname), "user.var_%d", j); snprintf(value, sizeof(value), "value-%d", j); ret = fsetxattr(fd, attrname, value, strlen(value), XATTR_REPLACE); if (ret < 0) { if (errno == ENOSPC || errno == EDQUOT) break; pr_fail_err(name, "fsetxattr"); goto out_close; } } for (j = 0; j < i; j++) { char tmp[sizeof(value)]; snprintf(attrname, sizeof(attrname), "user.var_%d", j); snprintf(value, sizeof(value), "value-%d", j); ret = fgetxattr(fd, attrname, tmp, sizeof(tmp)); if (ret < 0) { pr_fail_err(name, "fgetxattr"); goto out_close; } if (strncmp(value, tmp, ret)) { pr_fail(stderr, "%s: fgetxattr values " "different %.*s vs %.*s\n", name, ret, value, ret, tmp); goto out_close; } } /* Determine how large a buffer we required... */ sz = flistxattr(fd, NULL, 0); if (sz < 0) { pr_fail_err(name, "flistxattr"); goto out_close; } buffer = malloc(sz); if (buffer) { /* ...and fetch */ sz = flistxattr(fd, buffer, sz); free(buffer); if (sz < 0) { pr_fail_err(name, "flistxattr"); goto out_close; } } for (j = 0; j < i; j++) { snprintf(attrname, sizeof(attrname), "user.var_%d", j); ret = fremovexattr(fd, attrname); if (ret < 0) { pr_fail_err(name, "fremovexattr"); goto out_close; } } (*counter)++; } while (opt_do_run && (!max_ops || *counter < max_ops)); rc = EXIT_SUCCESS; out_close: (void)close(fd); out: (void)stress_temp_dir_rm(name, pid, instance); return rc; }
static void file_read_checks(const char *path) { char buf1[16],buf2[8],buf3[32]; struct iovec vec[3]; int rc, f, cnt; off_t i; mlog("+open"); f = open(path, O_RDONLY); if (f < 0) return; // first look at the file's attributes mlog("+fstat"); rc = fstat(f, &sbuf); #ifdef CHECK_XATTR mlog("+flistxattr"); flistxattr(f, lbuf, MAXLISTBUF); mlog("+fgetxattr"); fgetxattr(f, "selinux", lbuf, MAXLISTBUF); #endif // readahead(f, NULL // Check reading mlog("+read"); cnt = 0; while((read(f, buf3, sizeof(buf3)) > 0) && cnt < 1000) cnt++; // lseek around mlog("+lseek"); if (rc == 0) lseek(f, sbuf.st_size, SEEK_SET); lseek(f, 100000, SEEK_SET); lseek(f, 0, SEEK_SET); // vectored reads vec[0].iov_base = (void*)&buf1; vec[0].iov_len = sizeof(buf1); vec[1].iov_base = (void*)&buf2; vec[1].iov_len = sizeof(buf2); vec[2].iov_base = (void*)&buf3; vec[2].iov_len = sizeof(buf3); mlog("+readv"); cnt = 0; while((readv(f, vec, 3) > 0) && cnt < 1000) cnt++; // check out pread syscall i = 0; mlog("+pread"); cnt = 0; while ((pread(f, buf1, sizeof(buf1), i) > 0) && cnt < 1000) { i += sizeof(buf1)*2; cnt++; } // flock mlog("+flock"); flock(f, LOCK_SH|LOCK_NB); flock(f, LOCK_UN); // fcntl ? // sendfile to localhost:discard #if defined(__linux__) setup_socket(); if (sfd >= 0) { mlog("+sendfile"); lseek(f, 0, SEEK_SET); sendfile(sfd, f, NULL, rc ? 100000 : sbuf.st_size); close(sfd); sfd = -1; } #endif // mmap each file if (rc == 0) { char *src; mlog("+mmap"); src = mmap(0, sbuf.st_size, PROT_READ, MAP_FILE | MAP_SHARED, f, 0); if (src != (char *)-1) { // Don't touch memory...or Mr. SIGBUS will visit you mlog("+munmap"); munmap(src, sbuf.st_size); } } close(f); }