Hello,
On Fri, 2008-12-19 at 18:25 -0700, Andreas Dilger wrote:
> I've been trying to get some feedback on some changes to the xattr patches,
> but haven't been able to contact any of the people who worked on these in
> Red Hat. Is it better to just email you directly (and/or this list), or
> file a bug in Bugzilla?
>
> In particular, we'd like to:
> - Always backup all xattrs on a file instead of current practise of filtering
> the xattrs at backup time. This ensures they are all available later on
> if needed, even if they are not all restored by default. The filtering
> would only be done at restore time, and that can be fixed if it is wrong.
> - Change the restoration of xattrs to be before any file data is written.
> This allows the xattrs to contain layout hints, which is important for
> distributed filesystems (Lustre, pNFS) and possibly also ext4, btrfs, XFS,
> that have smarter allocators that can take advantage of this in the future
> once they realize what is possible.
Please find the attached a patch which comes close to implementing the
above changes. The patch has been applied on top tar-1.20-6.
Comments/suggestions are most welcome.
While adding the last hunk in the patch viz.
---------------------------------------------------------------------
/* 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 }
------------------------------------------------------------------------
I noticed that to allow any xattr other than user and trusted we not
only need to change the code which decides which xattrs to store in
xattrs_xattrs_get & xattrs_xattrs_set but also add it corresponding
entry in xhdr_tab[].
Isn't this a redundant check or am I missing something here ?
How about using following hunk, instead of the above:
- /* 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 },
-
- /* ignore everything else in the xattr namespaces... */
- { "SCHILY.xattr", dummy_coder, dummy_decoder, false, true },
+ { "SCHILY.xattr", xattr_coder, xattr_decoder, false, true },
This would allow implementation of the change, which Andreas had
mentioned, about backing up all the xattrs (patch as of now only adds
"SCHILY.xattr.lustre"). And the xattrs to be re-stored can be restricted
in xattrs_xattrs_set()
Thanks,
Girish
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: Girish Shilamkar <[email protected]>
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
@@ -592,6 +592,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 +778,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 +846,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 },