Signed-off-by: Andreas Dilger Signed-off-by: Girish Shilamkar Index: tar-1.20/src/xattrs.c =================================================================== --- tar-1.20.orig/src/xattrs.c +++ tar-1.20/src/xattrs.c @@ -237,15 +237,13 @@ void xattrs_xattrs_get(struct tar_stat_i { size_t len = strlen (attr); ssize_t aret = 0; - - if (strncmp (attr, "user.", strlen("user.")) && - strncmp (attr, "trusted.", strlen("trusted."))) - goto next_attr; /* only store normal xattrs */ - - while (((fd == -1) ? - ((aret = getxattr (file_name, attr, val, asz)) == -1) : - ((aret = fgetxattr (fd, attr, val, asz)) == -1)) && - (errno == ERANGE)) + + /* Archive all xattrs during creation, decide at extraction time + * which ones are of interest/use for the target filesystem. */ + while (((fd == -1) ? + ((aret = getxattr (file_name, attr, val, asz)) == -1) : + ((aret = fgetxattr (fd, attr, val, asz)) == -1)) && + (errno == ERANGE)) { asz <<= 1; val = xrealloc (val, asz); @@ -476,6 +474,7 @@ void xattrs_xattrs_set(struct tar_stat_i keyword += strlen("SCHILY.xattr."); if (strncmp (keyword, "user.", strlen("user.")) && + strncmp (keyword, "lustre.", strlen("lustre.")) && strncmp (keyword, "trusted.", strlen("trusted."))) continue; /* don't try and set anything but normal xattrs */ Index: tar-1.20/src/extract.c =================================================================== --- tar-1.20.orig/src/extract.c +++ tar-1.20/src/extract.c @@ -297,7 +297,6 @@ set_stat (char const *file_name, xattrs_acls_set(st, file_name, typeflag); xattrs_selinux_set(st, file_name, typeflag); - xattrs_xattrs_set(st, file_name, typeflag); if (0 < same_owner_option && permstatus != INTERDIR_PERMSTATUS) { @@ -592,6 +591,31 @@ maybe_recoverable (char *file_name, int } } +/* Restore stat extended attributes (xattr) for FILE_NAME, using information + given in *ST. Restore before extraction because they may affect layout. + If not restoring permissions, invert the + INVERT_PERMISSIONS bits from the file's current permissions. + TYPEFLAG specifies the type of the file. + FILE_CREATED indicates set_xattr has created the file */ +static int +set_xattr (char const *file_name, struct tar_stat_info const *st, + mode_t invert_permissions, char typeflag, int *file_created) +{ + int status = 0; + int interdir_made = 0; + + if ((xattrs_option >= 0) && st->xattr_map_size) { + mode_t mode = current_stat_info.stat.st_mode & MODE_RWX & ~ current_umask; + + do + status = mknod (file_name, mode ^ invert_permissions, 0); + while (status && maybe_recoverable ((char *)file_name, &interdir_made)); + xattrs_xattrs_set(st, file_name, typeflag); + *file_created = 1; + } + return(status); +} + /* Fix the statuses of all directories whose statuses need fixing, and which are not ancestors of FILE_NAME. If AFTER_LINKS is nonzero, do this for all such directories; otherwise, stop at the @@ -753,13 +777,17 @@ extract_dir (char *file_name, int typefl static int -open_output_file (char *file_name, int typeflag, mode_t mode) +open_output_file (char *file_name, int typeflag, mode_t mode, int file_created) { int fd; int openflag = (O_WRONLY | O_BINARY | O_CREAT - | (old_files_option == OVERWRITE_OLD_FILES - ? O_TRUNC - : O_EXCL)); + | (old_files_option == OVERWRITE_OLD_FILES + ? O_TRUNC + : O_EXCL)); + + /* File might be created in set_xattr. So clear O_EXCL to avoid open() failure */ + if (file_created) + openflag = openflag & ~O_EXCL; #if O_CTG /* Contiguous files (on the Masscomp) have to specify the size in @@ -817,8 +845,18 @@ extract_file (char *file_name, int typef } else { + int file_created = 0; + if (set_xattr (file_name, ¤t_stat_info, invert_permissions, + typeflag, &file_created)) + { + skip_member (); + open_error (file_name); + return 1; + } + do - fd = open_output_file (file_name, typeflag, mode ^ invert_permissions); + fd = open_output_file (file_name, typeflag, mode ^ invert_permissions, + file_created); while (fd < 0 && maybe_recoverable (file_name, &interdir_made)); if (fd < 0) Index: tar-1.20/src/xheader.c =================================================================== --- tar-1.20.orig/src/xheader.c +++ tar-1.20/src/xheader.c @@ -1680,6 +1680,7 @@ struct xhdr_tab const xhdr_tab[] = { /* xattr's, use the star format note we only save the user/trusted varients... */ { "SCHILY.xattr.user", xattr_coder, xattr_decoder, false, true }, { "SCHILY.xattr.trusted", xattr_coder, xattr_decoder, false, true }, + { "SCHILY.xattr.lustre", xattr_coder, xattr_decoder, false, true }, /* ignore everything else in the xattr namespaces... */ { "SCHILY.xattr", dummy_coder, dummy_decoder, false, true },