int solaris_removexattr(const char *path, const char* key) { int ret = -1; int attrfd = -1; char *mapped_path = NULL; ret = solaris_xattr_resolve_path (path, &mapped_path); if (!ret) { attrfd = attropen (mapped_path, ".", O_RDONLY, 0); } else { attrfd = attropen (path, ".", O_RDONLY, 0); } if (attrfd >= 0) { ret = unlinkat (attrfd, key, 0); close (attrfd); } else { if (errno == ENOENT) errno = ENODATA; ret = -1; } if (mapped_path) GF_FREE (mapped_path); return ret; }
/* * Gets file descriptors of attribute directories for source and target * attribute files */ int get_attrdirs(int indfd, int outdfd, char *attrfile, int *sfd, int *tfd) { int pwdfd; int fd1; int fd2; pwdfd = open(".", O_RDONLY); if ((pwdfd != -1) && (fchdir(indfd) == 0)) { if ((fd1 = attropen(attrfile, ".", O_RDONLY)) == -1) { (void) fchdir(pwdfd); (void) close(pwdfd); return (1); } *sfd = fd1; } else { (void) fchdir(pwdfd); (void) close(pwdfd); return (1); } if (fchdir(outdfd) == 0) { if ((fd2 = attropen(attrfile, ".", O_RDONLY)) == -1) { (void) fchdir(pwdfd); (void) close(pwdfd); return (1); } *tfd = fd2; } else { (void) fchdir(pwdfd); (void) close(pwdfd); return (1); } (void) fchdir(pwdfd); return (0); }
int solaris_setxattr(const char *path, const char* key, const char *value, size_t size, int flags) { int attrfd = -1; int ret = 0; char *mapped_path = NULL; ret = solaris_xattr_resolve_path (path, &mapped_path); if (!ret) { attrfd = attropen (mapped_path, key, flags|O_CREAT|O_WRONLY, 0777); } else { attrfd = attropen (path, key, flags|O_CREAT|O_WRONLY, 0777); } if (attrfd >= 0) { ftruncate (attrfd, 0); ret = write (attrfd, value, size); close (attrfd); ret = 0; } else { if (errno != ENOENT) gf_log ("libglusterfs", GF_LOG_ERROR, "Couldn't set extended attribute for %s (%d)", path, errno); ret = -1; } if (mapped_path) GF_FREE (mapped_path); return ret; }
/* * Deletes the specified root information */ static uint32_t dfs_root_remove(const char *rootdir) { int attrdirfd; int err = 0; (void) rw_wrlock(&dfs_root_rwl); if ((attrdirfd = attropen(rootdir, ".", O_RDONLY)) > 0) { if (unlinkat(attrdirfd, DFS_ROOT_XATTR, 0) == -1) { if (errno != ENOENT) err = errno; } (void) close(attrdirfd); } else { err = errno; } (void) rw_unlock(&dfs_root_rwl); if (err != 0) { syslog(LOG_DEBUG, "dfs: failed to remove root info %s (%d)", rootdir, err); return (ERROR_INTERNAL_ERROR); } return (ERROR_SUCCESS); }
int solaris_getxattr(const char *path, const char* key, char *value, size_t size) { int attrfd = -1; int ret = 0; attrfd = attropen (path, key, O_RDONLY, 0); if (attrfd >= 0) { if (size == 0) { struct stat buf; fstat (attrfd, &buf); ret = buf.st_size; } else { ret = read (attrfd, value, size); } close (attrfd); } else { if (errno == ENOENT) errno = ENODATA; if (errno != ENOENT) gf_log ("libglusterfs", GF_LOG_DEBUG, "Couldn't read extended attribute for the file %s (%d)", path, errno); return -1; } return ret; }
int solaris_setxattr(const char *path, const char* key, const char *value, size_t size, int flags) { int attrfd = -1; int ret = 0; attrfd = attropen (path, key, flags|O_CREAT|O_WRONLY, 0777); if (attrfd >= 0) { ftruncate (attrfd, 0); ret = write (attrfd, value, size); close (attrfd); } else { if (errno != ENOENT) gf_log ("libglusterfs", GF_LOG_ERROR, "Couldn't set extended attribute for %s (%d)", path, errno); return -1; } return 0; }
static ssize_t xattr_listxattr(const char *path, char *namebuf, size_t size, int options) { int xfd; xfd = attropen(path, ".", O_RDONLY); return xattr_xflistxattr(xfd, namebuf, size, options); }
static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode) { int filedes = attropen(path, attrpath, oflag, mode); if (filedes == -1) { if (errno != ENOENT) errno = ENOATTR; } return filedes; }
ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size) { int attrfd; if ((attrfd = attropen(path, name, O_RDONLY)) < 0) { errno = ENOATTR; return -1; } return read_xattr(attrfd, value, size); }
static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode) { int filedes = attropen(path, attrpath, oflag, mode); if (filedes == -1) { if (errno == EINVAL) { errno = ENOTSUP; } else { errno = ENOATTR; } } return filedes; }
int solaris_listxattr(const char *path, char *list, size_t size) { int attrdirfd = -1; ssize_t len = 0; DIR *dirptr = NULL; struct dirent *dent = NULL; int newfd = -1; attrdirfd = attropen (path, ".", O_RDONLY, 0); if (attrdirfd >= 0) { newfd = dup(attrdirfd); dirptr = fdopendir(newfd); if (dirptr) { while ((dent = readdir(dirptr))) { size_t listlen = strlen(dent->d_name); if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) { /* we don't want "." and ".." here */ continue; } if (size == 0) { /* return the current size of the list of extended attribute names*/ len += listlen + 1; } else { /* check size and copy entrie + nul into list. */ if ((len + listlen + 1) > size) { errno = ERANGE; len = -1; break; } else { strncpy(list + len, dent->d_name, listlen); len += listlen; list[len] = '\0'; ++len; } } } if (closedir(dirptr) == -1) { close (attrdirfd); return -1; } } else { close (attrdirfd); return -1; } close (attrdirfd); } return len; }
int solaris_getxattr(const char *path, const char* key, char *value, size_t size) { int attrfd = -1; int ret = 0; char *mapped_path = NULL; ret = solaris_xattr_resolve_path (path, &mapped_path); if (!ret) { attrfd = attropen (mapped_path, key, O_RDONLY, 0); } else { attrfd = attropen (path, key, O_RDONLY, 0); } if (attrfd >= 0) { if (size == 0) { struct stat buf; fstat (attrfd, &buf); ret = buf.st_size; } else { ret = read (attrfd, value, size); } close (attrfd); } else { if (errno != ENOENT) gf_log ("libglusterfs", GF_LOG_INFO, "Couldn't read extended attribute for the file %s (%s)", path, strerror (errno)); if (errno == ENOENT) errno = ENODATA; ret = -1; } if (mapped_path) GF_FREE (mapped_path); return ret; }
int sys_lremovexattr(const char *path, const char *name) { int attrdirfd; int ret; if ((attrdirfd = attropen(path, ".", O_RDONLY)) < 0) return -1; ret = unlinkat(attrdirfd, name, 0); close(attrdirfd); return ret; }
int sys_getxattrfd(const char *path, const char *uname, int oflag, ...) { #if defined HAVE_ATTROPEN int eafd; va_list args; mode_t mode; if (oflag & O_CREAT) { va_start(args, oflag); mode = va_arg(args, mode_t); va_end(args); } if (oflag & O_CREAT) eafd = attropen(path, uname, oflag, mode); else eafd = attropen(path, uname, oflag); return eafd; #else errno = ENOSYS; return -1; #endif }
int solaris_removexattr(const char *path, const char* key) { int ret = -1; int attrfd = attropen (path, ".", O_RDONLY, 0); if (attrfd >= 0) { ret = unlinkat (attrfd, key, 0); close (attrfd); } else { if (errno == ENOENT) errno = ENODATA; return -1; } return ret; }
ssize_t sys_llistxattr(const char *path, char *list, size_t size) { int attrdirfd; DIR *dirp; struct dirent *dp; ssize_t ret = 0; if ((attrdirfd = attropen(path, ".", O_RDONLY)) < 0) { errno = ENOTSUP; return -1; } if ((dirp = fdopendir(attrdirfd)) == NULL) { close(attrdirfd); return -1; } while ((dp = readdir(dirp))) { int len = strlen(dp->d_name); if (dp->d_name[0] == '.' && (len == 1 || (len == 2 && dp->d_name[1] == '.'))) continue; if (len == 11 && dp->d_name[0] == 'S' && strncmp(dp->d_name, "SUNWattr_r", 10) == 0 && (dp->d_name[10] == 'o' || dp->d_name[10] == 'w')) continue; if ((ret += len+1) > size) { if (size == 0) continue; ret = -1; errno = ERANGE; break; } memcpy(list, dp->d_name, len+1); list += len+1; } closedir(dirp); close(attrdirfd); return ret; }
int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size) { int attrfd; size_t bufpos; mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; if ((attrfd = attropen(path, name, O_CREAT|O_TRUNC|O_WRONLY, mode)) < 0) return -1; for (bufpos = 0; bufpos < size; ) { ssize_t cnt = write(attrfd, value+bufpos, size); if (cnt <= 0) { if (cnt < 0 && errno == EINTR) continue; bufpos = -1; break; } bufpos += cnt; } close(attrfd); return bufpos > 0 ? 0 : -1; }
/* * mv_xattrs - Copies the content of the extended attribute files. Then * moves the extended system attributes from the input attribute files * to the target attribute files. Moves the extended system attributes * from source to the target file. This function returns 0 on success * and nonzero on error. */ int mv_xattrs(char *cmd, char *infile, char *outfile, int sattr, int silent) { int srcfd = -1; int indfd = -1; int outdfd = -1; int tmpfd = -1; int sattrfd = -1; int tattrfd = -1; int asfd = -1; int atfd = -1; DIR *dirp = NULL; struct dirent *dp = NULL; char *etext = NULL; struct stat st1; struct stat st2; nvlist_t *response = NULL; nvlist_t *res = NULL; if ((srcfd = open(infile, O_RDONLY)) == -1) { etext = dgettext(TEXT_DOMAIN, "cannot open source"); goto error; } if (sattr) response = sysattr_list(cmd, srcfd, infile); if ((indfd = openat(srcfd, ".", O_RDONLY|O_XATTR)) == -1) { etext = dgettext(TEXT_DOMAIN, "cannot openat source"); goto error; } if ((outdfd = attropen(outfile, ".", O_RDONLY)) == -1) { etext = dgettext(TEXT_DOMAIN, "cannot attropen target"); goto error; } if ((tmpfd = dup(indfd)) == -1) { etext = dgettext(TEXT_DOMAIN, "cannot dup descriptor"); goto error; } if ((dirp = fdopendir(tmpfd)) == NULL) { etext = dgettext(TEXT_DOMAIN, "cannot access source"); goto error; } while ((dp = readdir(dirp)) != NULL) { if ((dp->d_name[0] == '.' && dp->d_name[1] == '\0') || (dp->d_name[0] == '.' && dp->d_name[1] == '.' && dp->d_name[2] == '\0') || (sysattr_type(dp->d_name) == _RO_SATTR) || (sysattr_type(dp->d_name) == _RW_SATTR)) continue; if ((sattrfd = openat(indfd, dp->d_name, O_RDONLY)) == -1) { etext = dgettext(TEXT_DOMAIN, "cannot open src attribute file"); goto error; } if (fstat(sattrfd, &st1) < 0) { etext = dgettext(TEXT_DOMAIN, "could not stat attribute file"); goto error; } if ((tattrfd = openat(outdfd, dp->d_name, O_RDWR|O_CREAT|O_TRUNC, st1.st_mode)) == -1) { etext = dgettext(TEXT_DOMAIN, "cannot open target attribute file"); goto error; } if (fstat(tattrfd, &st2) < 0) { etext = dgettext(TEXT_DOMAIN, "could not stat attribute file"); goto error; } if (writefile(sattrfd, tattrfd, infile, outfile, dp->d_name, dp->d_name, &st1, &st2) != 0) { etext = dgettext(TEXT_DOMAIN, "failed to copy extended attribute " "from source to target"); goto error; } errno = 0; if (sattr) { /* * Gets non default extended system attributes from * source to copy to target. */ if (dp->d_name != NULL) res = sysattr_list(cmd, sattrfd, dp->d_name); if (res != NULL && get_attrdirs(indfd, outdfd, dp->d_name, &asfd, &atfd) != 0) { etext = dgettext(TEXT_DOMAIN, "Failed to open attribute files"); goto error; } /* * Copy extended system attribute from source * attribute file to target attribute file */ if (res != NULL && (renameat(asfd, VIEW_READWRITE, atfd, VIEW_READWRITE) != 0)) { if (errno == EPERM) etext = dgettext(TEXT_DOMAIN, "Permission denied -" "failed to move system attribute"); else etext = dgettext(TEXT_DOMAIN, "failed to move extended " "system attribute"); goto error; } } if (sattrfd != -1) (void) close(sattrfd); if (tattrfd != -1) (void) close(tattrfd); if (asfd != -1) (void) close(asfd); if (atfd != -1) (void) close(atfd); if (res != NULL) { nvlist_free(res); res = NULL; } } errno = 0; /* Copy extended system attribute from source to target */ if (response != NULL) { if (renameat(indfd, VIEW_READWRITE, outdfd, VIEW_READWRITE) == 0) goto done; if (errno == EPERM) etext = dgettext(TEXT_DOMAIN, "Permission denied"); else etext = dgettext(TEXT_DOMAIN, "failed to move system attribute"); } error: nvlist_free(res); if (silent == 0 && etext != NULL) { if (!sattr) (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "%s: %s: cannot move extended attributes, "), cmd, infile); else (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "%s: %s: cannot move extended system " "attributes, "), cmd, infile); perror(etext); } done: if (dirp) (void) closedir(dirp); if (sattrfd != -1) (void) close(sattrfd); if (tattrfd != -1) (void) close(tattrfd); if (asfd != -1) (void) close(asfd); if (atfd != -1) (void) close(atfd); if (indfd != -1) (void) close(indfd); if (outdfd != -1) (void) close(outdfd); nvlist_free(response); if (etext != NULL) return (1); else return (0); }
/*ARGSUSED*/ longlong_t tlm_output_xattr(char *dir, char *name, char *chkdir, tlm_acls_t *tlm_acls, tlm_commands_t *commands, tlm_cmd_t *local_commands, tlm_job_stats_t *job_stats) { char *fullname; /* directory + name */ char *snapname; /* snapshot name */ int section; /* section of a huge file */ int fd; int afd = 0; longlong_t seek_spot = 0; /* location in the file */ /* for Multi Volume record */ DIR *dp; struct dirent *dtp; char *attrname; char *fnamep; int rv = 0; if (S_ISPECIAL(tlm_acls->acl_attr.st_mode)) { return (TLM_NO_SOURCE_FILE); } fullname = ndmp_malloc(TLM_MAX_PATH_NAME); if (fullname == NULL) { free(fullname); return (-TLM_NO_SCRATCH_SPACE); } if (!tlm_cat_path(fullname, dir, name)) { syslog(LOG_ERR, "Path too long."); free(fullname); return (-TLM_NO_SCRATCH_SPACE); } if (pathconf(fullname, _PC_XATTR_EXISTS) != 1 && sysattr_support(fullname, _PC_SATTR_EXISTS) != 1) { free(fullname); return (0); } attrname = ndmp_malloc(TLM_MAX_PATH_NAME); snapname = ndmp_malloc(TLM_MAX_PATH_NAME); if (attrname == NULL || snapname == NULL) { rv = -TLM_NO_SCRATCH_SPACE; goto err_out; } if (!tlm_cat_path(snapname, chkdir, name)) { syslog(LOG_ERR, "Path too long."); rv = -TLM_NO_SCRATCH_SPACE; goto err_out; } fnamep = (tlm_acls->acl_checkpointed) ? snapname : fullname; /* * Open the file for reading. */ fd = attropen(fnamep, ".", O_RDONLY); if (fd == -1) { syslog(LOG_ERR, "BACKUP> Can't open file [%s][%s]", fullname, fnamep); rv = TLM_NO_SOURCE_FILE; goto err_out; } section = 0; dp = (DIR *)fdopendir(fd); if (dp == NULL) { syslog(LOG_ERR, "BACKUP> Can't open file [%s]", fullname); (void) close(fd); rv = TLM_NO_SOURCE_FILE; goto err_out; } while ((dtp = readdir(dp)) != NULL) { int section_size; if (*dtp->d_name == '.') continue; if (sysattr_rdonly(dtp->d_name)) continue; afd = attropen(fnamep, dtp->d_name, O_RDONLY); if (afd == -1) { syslog(LOG_ERR, "problem(%d) opening xattr file [%s][%s]", errno, fullname, fnamep); goto tear_down; } (void) output_xattr_header(fullname, dtp->d_name, afd, tlm_acls, section, local_commands); (void) snprintf(attrname, TLM_MAX_PATH_NAME, "/dev/null/%s", dtp->d_name); (void) output_file_header(attrname, "", tlm_acls, 0, local_commands); section_size = (long)llmin(tlm_acls->acl_attr.st_size, (longlong_t)TLM_MAX_TAR_IMAGE); /* We only can read upto one section extended attribute */ while (section_size > 0) { char *buf; long actual_size; int read_size; int sysattr_read = 0; char *rec; int size; /* * check for Abort commands */ if (commands->tcs_reader != TLM_BACKUP_RUN) { local_commands->tc_writer = TLM_ABORT; goto tear_down; } local_commands->tc_buffers->tbs_buffer[ local_commands->tc_buffers->tbs_buffer_in]. tb_file_size = section_size; local_commands->tc_buffers->tbs_buffer[ local_commands->tc_buffers->tbs_buffer_in]. tb_seek_spot = seek_spot; buf = get_write_buffer(section_size, &actual_size, FALSE, local_commands); if (!buf) goto tear_down; if ((actual_size < section_size) && sysattr_rw(dtp->d_name)) { rec = buf; buf = ndmp_malloc(section_size); if (!buf) goto tear_down; size = actual_size; actual_size = section_size; sysattr_read = 1; } /* * check for Abort commands */ if (commands->tcs_reader != TLM_BACKUP_RUN) { local_commands->tc_writer = TLM_ABORT; goto tear_down; } read_size = min(section_size, actual_size); if ((actual_size = read(afd, buf, read_size)) < 0) break; if (sysattr_read) { if (get_write_one_buf(buf, rec, read_size, size, local_commands) == 0) { free(buf); goto tear_down; } free(buf); } NS_ADD(rdisk, actual_size); NS_INC(rfile); if (actual_size == -1) { syslog(LOG_ERR, "problem(%d) reading file [%s][%s]", errno, fullname, snapname); goto tear_down; } seek_spot += actual_size; section_size -= actual_size; } (void) close(afd); afd = -1; } tear_down: local_commands->tc_buffers->tbs_buffer[ local_commands->tc_buffers->tbs_buffer_in].tb_seek_spot = 0; if (afd > 0) (void) close(afd); /* closedir closes fd too */ (void) closedir(dp); err_out: free(fullname); free(attrname); free(snapname); return (rv); }