How to preserve NFS v4 ACLs via extended attributes when copying file

Solution Verified - Updated -

Environment

  • Red Hat Enterprise Linux 7
  • Red Hat Enterprise Linux 8

Issue

  • How can I preserve NFS v4 ACLs via extended attributes when copying file(s)?
  • rsync is unable to preserve NFS v4 ACLs via extended attributes (i.e., system.nfs4_acl)

Resolution

  • User space utilities are capable of transferring the NFSv4 ACLs using extended attributes.
  1. cp --preserve=xattr
  2. tar --xattrs
  3. rsync -X requires rsync-3.1.2-10.el7 or later on RHEL 7. RHEL 8 has rsync 3.1.3-4-el8 by default.

Diagnostic Steps

Table of Contents

Test Environment Setup
Example using cp command.
Example using tar command.
Attempt using rsync version 3.1.2
Example using upstream rsync version 3.1.3


Test Environment Setup

Note: This is just quick setup on RHEL 7 system to demonstrate the following examples.

  1. With NFS already running on server, export a test directory. When done do not forget to exportfs -u 127.0.0.1:/scratch/test.

    # exportfs -o rw,no_root_squash 127.0.0.1:/scratch/test
    
  2. Create a mount directory and mount via NFSv4

    # mkdir xattr
    # mount -t nfs4,rw,soft localhost:/scratch/test xattr
    
  3. Change directory, and create a file for testing.

    # cd xattr/
    # touch file
    
    # nfs4_getfacl file
    A::OWNER@:rwatTcCy <--.
    A::GROUP@:rtcy        |-- standard Unix perms
    A::EVERYONE@:rtcy <---'
    
  4. Add an NFSv4 ACL to the file.

    # nfs4_setfacl -a A::root@domain.com:rwaDdxtTnNcCoy file 
    # nfs4_getfacl file
    D::OWNER@:x
    A::OWNER@:rwatTcCy
    A::0:rwaxtcy <---- root group in '@domain.com' NFSv4 Domain
    A::GROUP@:rtcy
    A::EVERYONE@:rtcy
    

Back to Table of Contents

Example using cp command.

  1. Basic cp or cp -p will not preserve the NFSv4 ACL

    # cp -p file file.cp-p
    # nfs4_getfacl file.cp-p 
    D::OWNER@:x
    A::OWNER@:rwatTcCy
    A::GROUP@:rwaxtcy
    A::EVERYONE@:rtcy
    
  2. With the --preserve=xattr or -a options, cp will retain the NFSv4 ACL. Recommend the --preserve=xattr as -a will not impact output or exit code (see info cp for more).

    # cp --preserve=xattr file file.cp-xattr
    # nfs4_getfacl file.cp-xattr 
    D::OWNER@:x
    A::OWNER@:rwatTcCy
    A::0:rwaxtcy <----- cp preserved NFSv4 ACL
    A::GROUP@:rtcy
    A::EVERYONE@:rtcy
    

Back to Table of Contents

Example using tar command.

  1. Create a destination directory where will place file.

    # mkdir dst
    
  2. Basic tar will not preserve the NFSv4 ACL

    #  tar -cf - file | tar -C ./dst/ -xf -
    # nfs4_getfacl dst/file 
    D::OWNER@:x
    A::OWNER@:rwatTcCy
    A::GROUP@:rwaxtcy
    A::EVERYONE@:rtcy
    
  3. With the --xattrs-include=system.nfs4_acl or --xattrs --xattrs-include=* options, tar will retain the NFSv4 ACL.

    #  tar --xattrs-include=system.nfs4_acl -cf - file | tar --xattrs-include=system.nfs4_acl -C ./dst/ -xf -
    # nfs4_getfacl dst/file 
    D::OWNER@:x
    A::OWNER@:rwatTcCy
    A::0:rwaxtcy <----- tar preserved NFSv4 ACL
    A::GROUP@:rtcy
    A::EVERYONE@:rtcy
    

Back to Table of Contents

Attempt using rsync version 3.1.2

  1. Showing rsync version output

    # rsync --version | grep -w version
    rsync  version 3.1.2  protocol version 31
    
  2. Using -X or -XX options as root fail to preserve NFSv4 ACL

    # rsync -X file file.rsync-X
    # nfs4_getfacl file.rsync-X 
    D::OWNER@:x
    A::OWNER@:rwatTcCy
    A::GROUP@:rxtcy
    A::EVERYONE@:rtcy
    
  3. strace shows that getxattr() is failing for the system.posix_acl_default extended attribute name.

    # strace -fe getxattr  rsync -X file file.rsync-X 2>&1 | grep -i xattr
    [pid  1585] getxattr(".", "system.posix_acl_default", 0x7ffe575a70b0, 132) = -1 EOPNOTSUPP (Operation not supported)
    [pid  1586] getxattr(".", "system.posix_acl_default", 0x7ffe575a6300, 132) = -1 EOPNOTSUPP (Operation not supported)
    

Back to Table of Contents

Example using upstream rsync version 3.1.3

Note: This version allows user to filter extended attribute names via --filter. Using this new feature does allow following to preserve the NFSv4 ACLs.

  1. Show using upstream (not from Red Hat) version 3.1.3

    # ../rsync-3.1.3 --version | grep -w version
    rsync  version 3.1.3  protocol version 31
    
  2. The -X option still not enough to preserve NFS v4 ACLs

    # ../rsync-3.1.3 -X file file.rsync-X-3.1.3
    # nfs4_getfacl file.rsync-X-3.1.3 
    D::OWNER@:x
    A::OWNER@:rwatTcCy
    A::GROUP@:rxtcy
    A::EVERYONE@:rtcy
    
  3. When exclude all but system.nfs4_acl extended attributes, the NFSv4 ACLs are preserved:

    # ../rsync-3.1.3 -X --filter='-x! system.nfs4_acl' file file.rsync-3.1.3
    # nfs4_getfacl file.rsync-3.1.3 
    D::OWNER@:x
    A::OWNER@:rwatTcCy
    A::0:rxtcy  <----- rsync 3.1.3 preserved NFSv4 ACL (upstream) as root
    A::GROUP@:rtcy 
    A::EVERYONE@:rtcy
    
  4. In fact just excluding the system.posix_acl extended attribute name works.

    # ../rsync-3.1.3 -X --filter='-x system.posix_acl' file file.no-posix_acl
    # nfs4_getfacl file.no-posix_acl 
    D::OWNER@:x
    A::OWNER@:rwatTcCy
    A::0:rxtcy  <----- rsync 3.1.3 preserved NFSv4 ACL (upstream) as root
    A::GROUP@:rtcy
    A::EVERYONE@:rtcy
    
  5. When not running as normal user, rsync uses some of its own extended attribute names that can cause problems. However, this can be overcome by using the --super option.

    $ whoami
    user
    
    $ ../rsync-3.1.3 -X --filter='-x system.posix_acl' file file.user
    rsync: rsync_xal_set: lsetxattr("/accounts/jump/02190882/xattr/.file.user.4cbo3i","user.rsync.system.nfs4_acl") failed: Operation not supported (95)
    rsync: rsync_xal_set: lremovexattr("/accounts/jump/02190882/xattr/.file.user.4cbo3i","system.nfs4_acl") failed: Input/output error (5)
    rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1189) [sender=3.1.3]
    
    $ ../rsync-3.1.3 --super -X --filter='-x system.posix_acl' file file.user--super
    $ nfs4_getfacl file.user--super 
    D::OWNER@:x
    A::OWNER@:rwatTcCy
    A::0:rwaxtcy   <----- rsync 3.1.3 preserved NFSv4 ACL (upstream) as user with --super
    A::GROUP@:rtcy
    A::EVERYONE@:rtcy
    

Back to Table of Contents

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Comments